SPI driver includes functional APIs and transactional APIs.
Functional APIs are feature/property target low level APIs. Functional APIs can be used for SPI initialization/configuration/operation for optimization/customization purpose. Using the functional API requires the knowledge of the SPI peripheral and how to organize functional APIs to meet the application requirements. All functional API use the peripheral base address as the first parameter. SPI functional operation groups provide the functional API set.
Transactional APIs are transaction target high level APIs. Transactional APIs can be used to enable the peripheral and in the application if the code size and performance of transactional APIs satisfy the requirements. If the code size and performance are a critical requirement, see the transactional API implementation and write a custom code. All transactional APIs use the spi_handle_t as the first parameter. Initialize the handle by calling the SPI_MasterTransferCreateHandle() or SPI_SlaveTransferCreateHandle() API.
Transactional APIs support asynchronous transfer. This means that the functions SPI_MasterTransferNonBlocking() and SPI_SlaveTransferNonBlocking() set up the interrupt for data transfer. When the transfer completes, the upper layer is notified through a callback function with the kStatus_SPI_Idle status.
Typical use case
SPI master transfer using an interrupt method
#define BUFFER_LEN (64)
spi_master_handle_t spiHandle;
volatile bool isFinished = false;
const uint8_t sendData[BUFFER_LEN] = [......];
uint8_t receiveBuff[BUFFER_LEN];
void SPI_UserCallback(SPI_Type *base, spi_master_handle_t *handle, status_t status, void *userData)
{
isFinished = true;
}
void main(void)
{
while (!isFinished)
{
}
}
SPI Send/receive using a DMA method
#define BUFFER_LEN (64)
spi_dma_handle_t spiHandle;
dma_handle_t g_spiTxDmaHandle;
dma_handle_t g_spiRxDmaHandle;
spi_config_t masterConfig;
volatile bool isFinished;
uint8_t sendData[BUFFER_LEN] = ...;
uint8_t receiveBuff[BUFFER_LEN];
void SPI_UserCallback(SPI_Type *base, spi_dma_handle_t *handle, status_t status, void *userData)
{
isFinished = true;
}
void main(void)
{
DMAMUX_Init(DMAMUX0);
DMAMUX_SetSource(DMAMUX0, SPI_TX_DMA_CHANNEL, SPI_TX_DMA_REQUEST);
DMAMUX_EnableChannel(DMAMUX0, SPI_TX_DMA_CHANNEL);
DMAMUX_SetSource(DMAMUX0, SPI_RX_DMA_CHANNEL, SPI_RX_DMA_REQUEST);
DMAMUX_EnableChannel(DMAMUX0, SPI_RX_DMA_CHANNEL);
DMA_Init(DMA0);
DMA_CreateHandle(&g_spiTxDmaHandle, DMA0, SPI_TX_DMA_CHANNEL);
DMA_CreateHandle(&g_spiRxDmaHandle, DMA0, SPI_RX_DMA_CHANNEL);
while (!isFinished)
{
}
}
|
#define | SPI_DUMMYDATA (0xFFU) |
| SPI dummy transfer data, the data is sent while txBuff is NULL. More...
|
|
|
typedef spi_master_handle_t | spi_slave_handle_t |
| Slave handle is the same with master handle.
|
|
typedef void(* | spi_master_callback_t )(SPI_Type *base, spi_master_handle_t *handle, status_t status, void *userData) |
| SPI master callback for finished transmit.
|
|
typedef void(* | spi_slave_callback_t )(SPI_Type *base, spi_slave_handle_t *handle, status_t status, void *userData) |
| SPI master callback for finished transmit.
|
|
|
enum | _spi_status {
kStatus_SPI_Busy = MAKE_STATUS(kStatusGroup_SPI, 0),
kStatus_SPI_Idle = MAKE_STATUS(kStatusGroup_SPI, 1),
kStatus_SPI_Error = MAKE_STATUS(kStatusGroup_SPI, 2)
} |
| Return status for the SPI driver. More...
|
|
enum | spi_clock_polarity_t {
kSPI_ClockPolarityActiveHigh = 0x0U,
kSPI_ClockPolarityActiveLow
} |
| SPI clock polarity configuration. More...
|
|
enum | spi_clock_phase_t {
kSPI_ClockPhaseFirstEdge = 0x0U,
kSPI_ClockPhaseSecondEdge
} |
| SPI clock phase configuration. More...
|
|
enum | spi_shift_direction_t {
kSPI_MsbFirst = 0x0U,
kSPI_LsbFirst
} |
| SPI data shifter direction options. More...
|
|
enum | spi_ss_output_mode_t {
kSPI_SlaveSelectAsGpio = 0x0U,
kSPI_SlaveSelectFaultInput = 0x2U,
kSPI_SlaveSelectAutomaticOutput = 0x3U
} |
| SPI slave select output mode options. More...
|
|
enum | spi_pin_mode_t {
kSPI_PinModeNormal = 0x0U,
kSPI_PinModeInput = 0x1U,
kSPI_PinModeOutput = 0x3U
} |
| SPI pin mode options. More...
|
|
enum | spi_data_bitcount_mode_t {
kSPI_8BitMode = 0x0U,
kSPI_16BitMode
} |
| SPI data length mode options. More...
|
|
enum | _spi_interrupt_enable {
kSPI_RxFullAndModfInterruptEnable = 0x1U,
kSPI_TxEmptyInterruptEnable = 0x2U,
kSPI_MatchInterruptEnable = 0x4U
} |
| SPI interrupt sources. More...
|
|
enum | _spi_flags {
kSPI_RxBufferFullFlag = SPI_S_SPRF_MASK,
kSPI_MatchFlag = SPI_S_SPMF_MASK,
kSPI_TxBufferEmptyFlag = SPI_S_SPTEF_MASK,
kSPI_ModeFaultFlag = SPI_S_MODF_MASK
} |
| SPI status flags. More...
|
|
|
void | SPI_MasterTransferCreateHandle (SPI_Type *base, spi_master_handle_t *handle, spi_master_callback_t callback, void *userData) |
| Initializes the SPI master handle. More...
|
|
status_t | SPI_MasterTransferBlocking (SPI_Type *base, spi_transfer_t *xfer) |
| Transfers a block of data using a polling method. More...
|
|
status_t | SPI_MasterTransferNonBlocking (SPI_Type *base, spi_master_handle_t *handle, spi_transfer_t *xfer) |
| Performs a non-blocking SPI interrupt transfer. More...
|
|
status_t | SPI_MasterTransferGetCount (SPI_Type *base, spi_master_handle_t *handle, size_t *count) |
| Gets the bytes of the SPI interrupt transferred. More...
|
|
void | SPI_MasterTransferAbort (SPI_Type *base, spi_master_handle_t *handle) |
| Aborts an SPI transfer using interrupt. More...
|
|
void | SPI_MasterTransferHandleIRQ (SPI_Type *base, spi_master_handle_t *handle) |
| Interrupts the handler for the SPI. More...
|
|
void | SPI_SlaveTransferCreateHandle (SPI_Type *base, spi_slave_handle_t *handle, spi_slave_callback_t callback, void *userData) |
| Initializes the SPI slave handle. More...
|
|
static status_t | SPI_SlaveTransferNonBlocking (SPI_Type *base, spi_slave_handle_t *handle, spi_transfer_t *xfer) |
| Performs a non-blocking SPI slave interrupt transfer. More...
|
|
static status_t | SPI_SlaveTransferGetCount (SPI_Type *base, spi_slave_handle_t *handle, size_t *count) |
| Gets the bytes of the SPI interrupt transferred. More...
|
|
static void | SPI_SlaveTransferAbort (SPI_Type *base, spi_slave_handle_t *handle) |
| Aborts an SPI slave transfer using interrupt. More...
|
|
void | SPI_SlaveTransferHandleIRQ (SPI_Type *base, spi_slave_handle_t *handle) |
| Interrupts a handler for the SPI slave. More...
|
|
struct spi_master_config_t |
struct spi_slave_config_t |
Data Fields |
uint8_t * | txData |
| Send buffer.
|
|
uint8_t * | rxData |
| Receive buffer.
|
|
size_t | dataSize |
| Transfer bytes.
|
|
uint32_t | flags |
| SPI control flag, useless to SPI. More...
|
|
uint32_t spi_transfer_t::flags |
struct _spi_master_handle |
#define SPI_DUMMYDATA (0xFFU) |
Enumerator |
---|
kStatus_SPI_Busy |
SPI bus is busy.
|
kStatus_SPI_Idle |
SPI is idle.
|
kStatus_SPI_Error |
SPI error.
|
Enumerator |
---|
kSPI_ClockPolarityActiveHigh |
Active-high SPI clock (idles low).
|
kSPI_ClockPolarityActiveLow |
Active-low SPI clock (idles high).
|
Enumerator |
---|
kSPI_ClockPhaseFirstEdge |
First edge on SPSCK occurs at the middle of the first cycle of a data transfer.
|
kSPI_ClockPhaseSecondEdge |
First edge on SPSCK occurs at the start of the first cycle of a data transfer.
|
Enumerator |
---|
kSPI_MsbFirst |
Data transfers start with most significant bit.
|
kSPI_LsbFirst |
Data transfers start with least significant bit.
|
Enumerator |
---|
kSPI_SlaveSelectAsGpio |
Slave select pin configured as GPIO.
|
kSPI_SlaveSelectFaultInput |
Slave select pin configured for fault detection.
|
kSPI_SlaveSelectAutomaticOutput |
Slave select pin configured for automatic SPI output.
|
Enumerator |
---|
kSPI_PinModeNormal |
Pins operate in normal, single-direction mode.
|
kSPI_PinModeInput |
Bidirectional mode.
Master: MOSI pin is input; Slave: MISO pin is input.
|
kSPI_PinModeOutput |
Bidirectional mode.
Master: MOSI pin is output; Slave: MISO pin is output.
|
Enumerator |
---|
kSPI_8BitMode |
8-bit data transmission mode
|
kSPI_16BitMode |
16-bit data transmission mode
|
Enumerator |
---|
kSPI_RxFullAndModfInterruptEnable |
Receive buffer full (SPRF) and mode fault (MODF) interrupt.
|
kSPI_TxEmptyInterruptEnable |
Transmit buffer empty interrupt.
|
kSPI_MatchInterruptEnable |
Match interrupt.
|
Enumerator |
---|
kSPI_RxBufferFullFlag |
Read buffer full flag.
|
kSPI_MatchFlag |
Match flag.
|
kSPI_TxBufferEmptyFlag |
Transmit buffer empty flag.
|
kSPI_ModeFaultFlag |
Mode fault flag.
|
The purpose of this API is to get the configuration structure initialized for use in SPI_MasterInit(). User may use the initialized structure unchanged in SPI_MasterInit(), or modify some fields of the structure before calling SPI_MasterInit(). After calling this API, the master is ready to transfer. Example:
- Parameters
-
config | pointer to master config structure |
void SPI_MasterInit |
( |
SPI_Type * |
base, |
|
|
const spi_master_config_t * |
config, |
|
|
uint32_t |
srcClock_Hz |
|
) |
| |
The configuration structure can be filled by user from scratch, or be set with default values by SPI_MasterGetDefaultConfig(). After calling this API, the slave is ready to transfer. Example
- Parameters
-
base | SPI base pointer |
config | pointer to master configuration structure |
srcClock_Hz | Source clock frequency. |
The purpose of this API is to get the configuration structure initialized for use in SPI_SlaveInit(). Modify some fields of the structure before calling SPI_SlaveInit(). Example:
- Parameters
-
config | pointer to slave configuration structure |
The configuration structure can be filled by user from scratch or be set with default values by SPI_SlaveGetDefaultConfig(). After calling this API, the slave is ready to transfer. Example
.
polarity = kSPIClockPolarity_ActiveHigh;
.phase = kSPIClockPhase_FirstEdge;
.direction = kSPIMsbFirst;
...
};
- Parameters
-
base | SPI base pointer |
config | pointer to master configuration structure |
void SPI_Deinit |
( |
SPI_Type * |
base | ) |
|
Calling this API resets the SPI module, gates the SPI clock. The SPI module can't work unless calling the SPI_MasterInit/SPI_SlaveInit to initialize module.
- Parameters
-
static void SPI_Enable |
( |
SPI_Type * |
base, |
|
|
bool |
enable |
|
) |
| |
|
inlinestatic |
- Parameters
-
base | SPI base pointer |
enable | pass true to enable module, false to disable module |
uint32_t SPI_GetStatusFlags |
( |
SPI_Type * |
base | ) |
|
- Parameters
-
- Returns
- SPI Status, use status flag to AND _spi_flags could get the related status.
void SPI_EnableInterrupts |
( |
SPI_Type * |
base, |
|
|
uint32_t |
mask |
|
) |
| |
- Parameters
-
base | SPI base pointer |
mask | SPI interrupt source. The parameter can be any combination of the following values:
- kSPI_RxFullAndModfInterruptEnable
- kSPI_TxEmptyInterruptEnable
- kSPI_MatchInterruptEnable
- kSPI_RxFifoNearFullInterruptEnable
- kSPI_TxFifoNearEmptyInterruptEnable
|
void SPI_DisableInterrupts |
( |
SPI_Type * |
base, |
|
|
uint32_t |
mask |
|
) |
| |
- Parameters
-
base | SPI base pointer |
mask | SPI interrupt source. The parameter can be any combination of the following values:
- kSPI_RxFullAndModfInterruptEnable
- kSPI_TxEmptyInterruptEnable
- kSPI_MatchInterruptEnable
- kSPI_RxFifoNearFullInterruptEnable
- kSPI_TxFifoNearEmptyInterruptEnable
|
static uint32_t SPI_GetDataRegisterAddress |
( |
SPI_Type * |
base | ) |
|
|
inlinestatic |
This API is used to provide a transfer address for the SPI DMA transfer configuration.
- Parameters
-
- Returns
- data register address
void SPI_MasterSetBaudRate |
( |
SPI_Type * |
base, |
|
|
uint32_t |
baudRate_Bps, |
|
|
uint32_t |
srcClock_Hz |
|
) |
| |
This is only used in master.
- Parameters
-
base | SPI base pointer |
baudRate_Bps | baud rate needed in Hz. |
srcClock_Hz | SPI source clock frequency in Hz. |
static void SPI_SetMatchData |
( |
SPI_Type * |
base, |
|
|
uint32_t |
matchData |
|
) |
| |
|
inlinestatic |
The match data is a hardware comparison value. When the value received in the SPI receive data buffer equals the hardware comparison value, the SPI Match Flag in the S register (S[SPMF]) sets. This can also generate an interrupt if the enable bit sets.
- Parameters
-
base | SPI base pointer |
matchData | Match data. |
void SPI_WriteBlocking |
( |
SPI_Type * |
base, |
|
|
uint8_t * |
buffer, |
|
|
size_t |
size |
|
) |
| |
- Note
- This function blocks via polling until all bytes have been sent.
- Parameters
-
base | SPI base pointer |
buffer | The data bytes to send |
size | The number of data bytes to send |
void SPI_WriteData |
( |
SPI_Type * |
base, |
|
|
uint16_t |
data |
|
) |
| |
- Parameters
-
base | SPI base pointer |
data | needs to be write. |
uint16_t SPI_ReadData |
( |
SPI_Type * |
base | ) |
|
- Parameters
-
- Returns
- Data in the register.
void SPI_MasterTransferCreateHandle |
( |
SPI_Type * |
base, |
|
|
spi_master_handle_t * |
handle, |
|
|
spi_master_callback_t |
callback, |
|
|
void * |
userData |
|
) |
| |
This function initializes the SPI master handle which can be used for other SPI master transactional APIs. Usually, for a specified SPI instance, call this API once to get the initialized handle.
- Parameters
-
base | SPI peripheral base address. |
handle | SPI handle pointer. |
callback | Callback function. |
userData | User data. |
status_t SPI_MasterTransferBlocking |
( |
SPI_Type * |
base, |
|
|
spi_transfer_t * |
xfer |
|
) |
| |
- Parameters
-
base | SPI base pointer |
xfer | pointer to spi_xfer_config_t structure |
- Return values
-
kStatus_Success | Successfully start a transfer. |
kStatus_InvalidArgument | Input argument is invalid. |
status_t SPI_MasterTransferNonBlocking |
( |
SPI_Type * |
base, |
|
|
spi_master_handle_t * |
handle, |
|
|
spi_transfer_t * |
xfer |
|
) |
| |
- Note
- The API immediately returns after transfer initialization is finished. Call SPI_GetStatusIRQ() to get the transfer status.
-
If using the SPI with FIFO for the interrupt transfer, the transfer size is the integer times of the watermark. Otherwise, the last data may be lost because it cannot generate an interrupt request. Users can also call the functional API to get the last received data.
- Parameters
-
base | SPI peripheral base address. |
handle | pointer to spi_master_handle_t structure which stores the transfer state |
xfer | pointer to spi_xfer_config_t structure |
- Return values
-
kStatus_Success | Successfully start a transfer. |
kStatus_InvalidArgument | Input argument is invalid. |
kStatus_SPI_Busy | SPI is not idle, is running another transfer. |
status_t SPI_MasterTransferGetCount |
( |
SPI_Type * |
base, |
|
|
spi_master_handle_t * |
handle, |
|
|
size_t * |
count |
|
) |
| |
- Parameters
-
base | SPI peripheral base address. |
handle | Pointer to SPI transfer handle, this should be a static variable. |
count | Transferred bytes of SPI master. |
- Return values
-
kStatus_SPI_Success | Succeed get the transfer count. |
kStatus_NoTransferInProgress | There is not a non-blocking transaction currently in progress. |
void SPI_MasterTransferAbort |
( |
SPI_Type * |
base, |
|
|
spi_master_handle_t * |
handle |
|
) |
| |
- Parameters
-
base | SPI peripheral base address. |
handle | Pointer to SPI transfer handle, this should be a static variable. |
void SPI_MasterTransferHandleIRQ |
( |
SPI_Type * |
base, |
|
|
spi_master_handle_t * |
handle |
|
) |
| |
- Parameters
-
base | SPI peripheral base address. |
handle | pointer to spi_master_handle_t structure which stores the transfer state. |
This function initializes the SPI slave handle which can be used for other SPI slave transactional APIs. Usually, for a specified SPI instance, call this API once to get the initialized handle.
- Parameters
-
base | SPI peripheral base address. |
handle | SPI handle pointer. |
callback | Callback function. |
userData | User data. |
- Note
- The API returns immediately after the transfer initialization is finished. Call SPI_GetStatusIRQ() to get the transfer status.
-
If using the SPI with FIFO for the interrupt transfer, the transfer size is the integer times the watermark. Otherwise, the last data may be lost because it cannot generate an interrupt request. Call the functional API to get the last several receive data.
- Parameters
-
base | SPI peripheral base address. |
handle | pointer to spi_master_handle_t structure which stores the transfer state |
xfer | pointer to spi_xfer_config_t structure |
- Return values
-
kStatus_Success | Successfully start a transfer. |
kStatus_InvalidArgument | Input argument is invalid. |
kStatus_SPI_Busy | SPI is not idle, is running another transfer. |
static status_t SPI_SlaveTransferGetCount |
( |
SPI_Type * |
base, |
|
|
spi_slave_handle_t * |
handle, |
|
|
size_t * |
count |
|
) |
| |
|
inlinestatic |
- Parameters
-
base | SPI peripheral base address. |
handle | Pointer to SPI transfer handle, this should be a static variable. |
count | Transferred bytes of SPI slave. |
- Return values
-
kStatus_SPI_Success | Succeed get the transfer count. |
kStatus_NoTransferInProgress | There is not a non-blocking transaction currently in progress. |
- Parameters
-
base | SPI peripheral base address. |
handle | Pointer to SPI transfer handle, this should be a static variable. |
- Parameters
-
base | SPI peripheral base address. |
handle | pointer to spi_slave_handle_t structure which stores the transfer state |