1 /* mbed Microcontroller Library
2 * Copyright (c) 2013 ARM Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "mbed_assert.h"
25 #include "mbed_error.h"
26 #include "fsl_clock_manager.h"
27 #include "fsl_dspi_hal.h"
28 #include "PeripheralPins.h"
30 void spi_init(spi_t
*obj
, PinName mosi
, PinName miso
, PinName sclk
, PinName ssel
) {
31 // determine the SPI to use
32 uint32_t spi_mosi
= pinmap_peripheral(mosi
, PinMap_SPI_MOSI
);
33 uint32_t spi_miso
= pinmap_peripheral(miso
, PinMap_SPI_MISO
);
34 uint32_t spi_sclk
= pinmap_peripheral(sclk
, PinMap_SPI_SCLK
);
35 uint32_t spi_ssel
= pinmap_peripheral(ssel
, PinMap_SPI_SSEL
);
36 uint32_t spi_data
= pinmap_merge(spi_mosi
, spi_miso
);
37 uint32_t spi_cntl
= pinmap_merge(spi_sclk
, spi_ssel
);
39 obj
->instance
= pinmap_merge(spi_data
, spi_cntl
);
40 MBED_ASSERT((int)obj
->instance
!= NC
);
42 CLOCK_SYS_EnableSpiClock(obj
->instance
);
43 uint32_t spi_address
[] = SPI_BASE_ADDRS
;
44 DSPI_HAL_Init(spi_address
[obj
->instance
]);
45 DSPI_HAL_Disable(spi_address
[obj
->instance
]);
46 // set default format and frequency
48 spi_format(obj
, 8, 0, 0); // 8 bits, mode 0, master
50 spi_format(obj
, 8, 0, 1); // 8 bits, mode 0, slave
52 DSPI_HAL_SetDelay(spi_address
[obj
->instance
], kDspiCtar0
, 0, 0, kDspiPcsToSck
);
53 spi_frequency(obj
, 1000000);
55 DSPI_HAL_Enable(spi_address
[obj
->instance
]);
56 DSPI_HAL_StartTransfer(spi_address
[obj
->instance
]);
58 // pin out the spi pins
59 pinmap_pinout(mosi
, PinMap_SPI_MOSI
);
60 pinmap_pinout(miso
, PinMap_SPI_MISO
);
61 pinmap_pinout(sclk
, PinMap_SPI_SCLK
);
63 pinmap_pinout(ssel
, PinMap_SPI_SSEL
);
67 void spi_free(spi_t
*obj
) {
70 void spi_format(spi_t
*obj
, int bits
, int mode
, int slave
) {
71 dspi_data_format_config_t config
= {0};
72 config
.bitsPerFrame
= (uint32_t)bits
;
73 config
.clkPolarity
= (mode
& 0x2) ? kDspiClockPolarity_ActiveLow
: kDspiClockPolarity_ActiveHigh
;
74 config
.clkPhase
= (mode
& 0x1) ? kDspiClockPhase_SecondEdge
: kDspiClockPhase_FirstEdge
;
75 config
.direction
= kDspiMsbFirst
;
76 uint32_t spi_address
[] = SPI_BASE_ADDRS
;
77 dspi_status_t result
= DSPI_HAL_SetDataFormat(spi_address
[obj
->instance
], kDspiCtar0
, &config
);
78 if (result
!= kStatus_DSPI_Success
) {
79 error("Failed to configure SPI data format");
83 DSPI_HAL_SetMasterSlaveMode(spi_address
[obj
->instance
], kDspiSlave
);
85 DSPI_HAL_SetMasterSlaveMode(spi_address
[obj
->instance
], kDspiMaster
);
89 void spi_frequency(spi_t
*obj
, int hz
) {
91 CLOCK_SYS_GetFreq(kBusClock
, &busClock
);
92 uint32_t spi_address
[] = SPI_BASE_ADDRS
;
93 DSPI_HAL_SetBaudRate(spi_address
[obj
->instance
], kDspiCtar0
, (uint32_t)hz
, busClock
);
96 static inline int spi_writeable(spi_t
* obj
) {
97 uint32_t spi_address
[] = SPI_BASE_ADDRS
;
98 return DSPI_HAL_GetStatusFlag(spi_address
[obj
->instance
], kDspiTxFifoFillRequest
);
101 static inline int spi_readable(spi_t
* obj
) {
102 uint32_t spi_address
[] = SPI_BASE_ADDRS
;
103 return DSPI_HAL_GetStatusFlag(spi_address
[obj
->instance
], kDspiRxFifoDrainRequest
);
106 int spi_master_write(spi_t
*obj
, int value
) {
107 uint32_t spi_address
[] = SPI_BASE_ADDRS
;
109 // wait tx buffer empty
110 while(!spi_writeable(obj
));
111 dspi_command_config_t command
= {0};
112 command
.isEndOfQueue
= true;
113 command
.isChipSelectContinuous
= 0;
114 DSPI_HAL_WriteDataMastermode(spi_address
[obj
->instance
], &command
, (uint16_t)value
);
115 DSPI_HAL_ClearStatusFlag(spi_address
[obj
->instance
], kDspiTxFifoFillRequest
);
117 // wait rx buffer full
118 while (!spi_readable(obj
));
119 DSPI_HAL_ClearStatusFlag(spi_address
[obj
->instance
], kDspiRxFifoDrainRequest
);
120 return DSPI_HAL_ReadData(spi_address
[obj
->instance
]) & 0xff;
123 int spi_slave_receive(spi_t
*obj
) {
124 return spi_readable(obj
);
127 int spi_slave_read(spi_t
*obj
) {
128 DSPI_HAL_ClearStatusFlag(obj
->instance
, kDspiRxFifoDrainRequest
);
129 uint32_t spi_address
[] = SPI_BASE_ADDRS
;
130 return DSPI_HAL_ReadData(spi_address
[obj
->instance
]);
133 void spi_slave_write(spi_t
*obj
, int value
) {
134 while (!spi_writeable(obj
));
135 uint32_t spi_address
[] = SPI_BASE_ADDRS
;
136 DSPI_HAL_WriteDataSlavemode(spi_address
[obj
->instance
], (uint32_t)value
);