This section describes the programming interface of the DSPI slave mode peripheral driver. The DSPI slave peripheral driver supports using the SPI peripheral in slave mode. It supports transferring buffers of data with a single function call. When the DSPI is configured for slave mode operations, it must first be set up to perform a transfer and then wait for the master to initiate the transfer.
The driver is separated into two implementations: interrupt driven and DMA driven. The interrupt driven driver uses interrupts to alert the CPU that the DSPI module needs to service the SPI data transmit and receive operations. The enhanced DMA (eDMA) driven driver uses the eDMA module to transfer data between the buffers located in memory and the DSPI module transmit/receive buffers/FIFOs. In the subsequent sections, the enhanced DMA-driven driver is referred to as the DMA-driven driver. The interrupt-driven and DMA-driven driver APIs are distinguished by the keyword "edma" in the source file name and by the keyword "Edma" in the API name. Each set of drivers have the same API functionality and are described in the following sections. Note that the DMA-driven driver also uses interrupts to alert the CPU that the DMA has completed its transfer or that one final piece of data still needs to be received which is handled by the IRQ handler in the DMA driven driver. In both the interrupt and DMA drivers, the SPI module interrupts are enabled in the NVIC. In addition, the DMA driven-driver requests channels from the eDMA module. In the subsequent sections, either set of drivers is referred to as the "DSPI slave driver" when discussing items that pertain to either driver. Note, when using the DMA driven DSPI driver, eDMA module needs to be initialized. An example is shown in the Initialization section.
This is a step-by-step overview to set up the DSPI for SPI slave mode operations. For API specific examples, see the examples below. This example uses the interrupt-driven APIs and a blocking transfer to illustrate a high-level step-by-step usage. The usage of eDMA driver is similar to interrupt-driven driver. Keep in mind that using interrupt and eDMA drivers in the same runtime application is not recommended because the SPI interrupt handler needs to be changed. The interrupt driver calls the DSPI_DRV_IRQHandler() function and the eDMA driver calls the DSPI_DRV_EdmaIRQHandler() function. See files fsl_dspi_irq.c and fsl_dspi_edma_irq.c for an example of these function calls.
Note that it is not normally recommended to mix interrupt and DMA-driven drivers in the same application. However, should the user decide to do so, separately set up and initialize another instance for DMA operations. The user can also de-initialize the current interrupt-driven DSPI instance and re-initialize it for DMA operations. Note, that, because the DMA-driven driver also uses interrupts, direct the IRQ handler from the vector table to the desired driver's IRQ handler. See files fsl_dspi_irq.c and fsl_dspi_edma_irq.c for examples to re-direct the IRQ handlers from the vector table to the interrupt-driven and DMA-driven driver IRQ handlers. These files need to be included in the applications project in order to direct the DSPI interrupt vectors to the proper IRQ handlers. The fsl_dspi_shared_function.c and fsl_dspi_edma_shared_function.c files direct the interrupts from the vector table to the appropriate master or slave driver interrupt handler by checking the DSPI mode via the HAL function DSPI_HAL_IsMaster(baseAddr).
When using the DSPI driver with the eDMA, some DSPI instances do not support separate DMA requests for transmit and receive channels. In those cases, with a single shared DMA request for transmit and receive DMA channels, the driver links one channel to the other in order to take advantage of DMA transfers. However, the drawback to using an instance with shared DMA requests limits the maximum amount of data the driver can transfer. This limit depends on the bits/frame setting.
For DSPI instances with separate transmit and receive DMA requests, the maximum number of bytes that can be transferred are: 8-bit setting: 32767 bytes 16-bit setting: 65534 bytes
For DSPI instances with a shared transmit and receive DMA request, the maximum number of bytes that can be transferred are: 8-bit setting: 511 bytes 16-bit setting: 1022 bytes
See the microcontroller-specific documentation to see which DSPI instance have separate or shared TX and RX DMA requests. Additionally, see the microcontroller-specific feature header file to see which DSPI instance have separate or shared transmit and receive DMA requests.
DSPI Runtime state of the DSPI slave driver
The DSPI slave driver uses a run-time state structure to track the ongoing data transfers. The state structure for the interrupt-driven driver is called the dspi_slave_state_t. The state structure for the DMA driven driver is called the dspi_edma_slave_state_t. The structure holds data that the DSPI slave peripheral driver uses to communicate between the transfer function and the interrupt handler and other driver functions. The interrupt handler also uses this information to keep track of its progress. The user is only responsible to pass the memory for this run-time state structure. The DSPI slave driver fills out the members.
DSPI User configuration structures
The DSPI slave driver uses instances of the user configuration structure for the DSPI slave driver. The user configuration structure for the interrupt driven driver is called the dspi_slave_user_config_t. The user configuration structure for the DMA driven driver is called the dspi_edma_slave_user_config_t. For this reason, the user can configure the most common settings of the DSPI peripheral with a single function call.
DSPI Setup and Initialization
To initialize the DSPI slave driver, first create and fill in a dspi_slave_user_config_t structure for the interrupt-driven driver or the dspi_edma_slave_user_config_t structure for the DMA-driven driver. This structure defines the data format settings for the SPI peripheral. The structure is not required after the driver is initialized and can be allocated on the stack. The user also must pass the memory for the run-time state structure.
This is an example code to initialize and configure the driver for interrupt and DMA operations:
uint32_t instance = 1;
uint32_t bitCount = 16;
DSPI Blocking and non-blocking
The DSPI slave driver has two types of transfer functions, blocking and non-blocking call. With non-blocking calls, the user starts the transfer and then waits for event flags to set. kDspiTxDone indicates the transmission is done and kDspiRxDone indicates reception is done. With the blocking call, the function only returns after the related process is completed.
This is an example of blocking and non-blocking call (interrupt driven):
sendBuffer,
receiveBuffer,
transferSize,
10000);
sendBuffer,
receiveBuffer,
transferSize);
Additionally, the DSPI supports eDMA transfers. To use the DSPI with DMA, see this example:
sendBuffer,
receiveBuffer,
transferSize,
10000);
sendBuffer,
receiveBuffer,
transferSize);
DSPI De-initialization
To de-initialize and shut down the DSPI module, call the function:
If using eDMA-driven method, call the function
struct dspi_dma_slave_user_config_t |
struct dspi_dma_slave_state_t |
This structure holds data that is used by the DSPI slave peripheral driver to communicate between the transfer function and the interrupt handler. The user needs to pass in the memory for this structure and the driver fills out the members.
struct dspi_edma_slave_user_config_t |
struct dspi_edma_slave_state_t |
This structure holds data that is used by the DSPI slave peripheral driver to communicate between the transfer function and the interrupt handler. The user needs to pass in the memory for this structure and the driver fills out the members.
struct dspi_slave_user_config_t |
struct dspi_slave_state_t |
This structure holds data that is used by the DSPI slave peripheral driver to communicate between the transfer function and the interrupt handler. The user needs to pass in the memory for this structure and the driver fills out the members.
volatile bool dspi_slave_state_t::isTransferInProgress |
volatile int32_t dspi_slave_state_t::remainingSendByteCount |
volatile int32_t dspi_slave_state_t::remainingReceiveByteCount |
This function ungates the clock to the DSPI module, initializes the DSPI for slave mode, and initializes DMA channels. After it is initialized, the DSPI module is configured in slave mode and the user can start transmitting and receiving data by calling send, receive, and transfer functions. This function indicates that the DSPI slave uses the DMA mechanism.
- Parameters
-
instance | The instance number of the DSPI peripheral. |
dspiState | The pointer to the DSPI slave driver state structure. |
slaveConfig | The configuration structure dspi_dma_slave_user_config_t which configures the data bus format. |
- Returns
- An error code or kStatus_DSPI_Success.
Disables the DSPI module, gates its clock, changes the DSPI slave driver state to NonInit for DSPI slave module, which is initialized with the DMA mechanism. After de-initialization, the user can re-initialize the DSPI slave module with other methods.
- Parameters
-
instance | The instance number of the DSPI peripheral. |
- Returns
- kStatus_DSPI_Success indicating successful de-initialization or error code
dspi_status_t DSPI_DRV_DmaSlaveTransferBlocking |
( |
uint32_t |
instance, |
|
|
const uint8_t * |
sendBuffer, |
|
|
uint8_t * |
receiveBuffer, |
|
|
uint32_t |
transferByteCount, |
|
|
uint32_t |
timeOut |
|
) |
| |
This function checks driver status and mechanism and transmits/receives data through the SPI bus. If the sendBuffer is NULL, transmit process is ignored. If the receiveBuffer is NULL, the receive process is ignored. If both the receiveBuffer and the sendBuffer are available, the progress of both the transmit and receive is processed. If only the receiveBuffer is available, the receive is processed, Otherwise, the transmit is processed. This function only returns when its processes are complete. This function uses the DMA mechanism.
- Parameters
-
instance | The instance number of DSPI peripheral |
sendBuffer | The pointer to data that user wants to transmit. |
receiveBuffer | The pointer to data that user wants to store received data. |
transferByteCount | The number of bytes to send and receive. |
timeOut | The maximum number of milliseconds that function waits before the timed out is reached. |
- Returns
- kStatus_DSPI_Success if driver starts to send/receive data successfully. kStatus_DSPI_Error if driver is error and needs to clean error. kStatus_DSPI_Busy if driver is receiving/transmitting data and not available. kStatus_DSPI_Timeout if time out reached while transferring is in progress.
dspi_status_t DSPI_DRV_DmaSlaveTransfer |
( |
uint32_t |
instance, |
|
|
const uint8_t * |
sendBuffer, |
|
|
uint8_t * |
receiveBuffer, |
|
|
uint32_t |
transferByteCount |
|
) |
| |
This function checks the driver status and sets buffer pointers to receive and transmit SPI data. If the sendBuffer is NULL, the transmit process is ignored. If the receiveBuffer is NULL, the receive process is ignored. If both the receiveBuffer and sendBuffer are available, the transfer is done when the kDspiTxDone and the kDspiRxDone flags are set. If only the receiveBuffer is available, the transfer is done when the kDspiRxDone flag is set. Otherwise, the transfer is done when the kDspiTxDone flag is set. This function uses the DMA mechanism.
- Parameters
-
instance | The instance number of DSPI peripheral. |
sendBuffer | The pointer to data that user wants to transmit. |
receiveBuffer | The pointer to data that user wants to store received data. |
transferByteCount | The number of bytes to send and receive. |
- Returns
- kStatus_DSPI_Success if driver starts to send/receive data successfully. kStatus_DSPI_Error if driver is error and needs to clean error. kStatus_DSPI_Busy if driver is receiving/transmitting data and not available.
dspi_status_t DSPI_DRV_DmaSlaveAbortTransfer |
( |
uint32_t |
instance | ) |
|
This function stops the transfer which was started by the DSPI_DRV_DmaSlaveTransfer() function.
- Parameters
-
instance | The instance number of DSPI peripheral |
- Returns
- kStatus_DSPI_Success if everything is OK. kStatus_DSPI_InvalidMechanism if the current transaction does not use DMA mechanism.
dspi_status_t DSPI_DRV_DmaSlaveGetTransferStatus |
( |
uint32_t |
instance, |
|
|
uint32_t * |
framesTransferred |
|
) |
| |
When performing an a-sync transfer, call this function to ascertain the state of the current transfer: in progress (or busy) or complete (success). In addition, if the transfer is still in progress, the user can get the number of words that have been transferred up to that point.
- Parameters
-
instance | The instance number of the DSPI peripheral. |
framesTransferred | Pointer to value that is filled in with the number of frames that have been sent in the active transfer. A frame is defined as the number of bits per frame. |
- Returns
- kStatus_DSPI_Success The transfer has completed successfully, or kStatus_DSPI_Busy The transfer is still in progress. framesTransferred is filled with the number of words that have been transferred so far.
This function un-gates the clock to the DSPI module, initializes the DSPI for slave mode and initializes eDMA channels. After it is initialized, the DSPI module is configured in slave mode and user can start transmit, receive data by calls send, receive, transfer functions. This function indicates DSPI slave uses the eDMA mechanism.
- Parameters
-
instance | The instance number of the DSPI peripheral. |
dspiState | The pointer to the DSPI slave driver state structure. |
slaveConfig | The configuration structure dspi_edma_slave_user_config_t which configures the data bus format. |
- Returns
- An error code or kStatus_DSPI_Success.
Disables the DSPI module, gates its clock, changes the DSPI slave driver state to NonInit for DSPI slave module which is initialized with the eDMA mechanism. After de-initialization, the user can re-initialize the DSPI slave module with other mechanisms.
- Parameters
-
instance | The instance number of the DSPI peripheral. |
- Returns
- kStatus_DSPI_Success indicating successful de-initialization or error code
dspi_status_t DSPI_DRV_EdmaSlaveTransferBlocking |
( |
uint32_t |
instance, |
|
|
const uint8_t * |
sendBuffer, |
|
|
uint8_t * |
receiveBuffer, |
|
|
uint32_t |
transferByteCount, |
|
|
uint32_t |
timeOut |
|
) |
| |
This function checks driver status, mechanism and transmits/receives data through SPI bus. If sendBuffer is NULL, transmit process is ignored, and if the receiveBuffer is NULL, the receive process is ignored. If both the receiveBuffer and the sendBuffer are available, the transmit and receive progress is processed. If only the receiveBuffer is available, the receive is processed, Otherwise, the transmit is processed. This function only returns when its processes are complete. This function uses the eDMA mechanism.
- Parameters
-
instance | The instance number of DSPI peripheral |
sendBuffer | The pointer to data that user wants to transmit. |
receiveBuffer | The pointer to data that user wants to store received data. |
transferByteCount | The number of bytes to send and receive. |
timeOut | The maximum number of milliseconds that function will wait before timed out reached. |
- Returns
- kStatus_DSPI_Success if driver starts to send/receive data successfully. kStatus_DSPI_Error if driver is error and needs to clean error. kStatus_DSPI_Busy if driver is receiving/transmitting data and not available. kStatus_DSPI_Timeout if time out reached while transferring is in progress.
dspi_status_t DSPI_DRV_EdmaSlaveTransfer |
( |
uint32_t |
instance, |
|
|
const uint8_t * |
sendBuffer, |
|
|
uint8_t * |
receiveBuffer, |
|
|
uint32_t |
transferByteCount |
|
) |
| |
This function checks the driver status then sets buffer pointers to receive and transmit SPI data. If the sendBuffer is NULL, transmit process is ignored. If the receiveBuffer is NULL, the receive process is ignored. If both the receiveBuffer and sendBuffer are available, the transfer is done when the kDspiTxDone and the kDspiRxDone are set. If only the receiveBuffer is available, the transfer is done when the kDspiRxDone flag is set. Otherwise, the transfer is done when the kDspiTxDone is set. This function uses the eDMA mechanism.
- Parameters
-
instance | The instance number of DSPI peripheral. |
sendBuffer | The pointer to data that user wants to transmit. |
receiveBuffer | The pointer to data that user wants to store received data. |
transferByteCount | The number of bytes to send and receive. |
- Returns
- kStatus_DSPI_Success if driver starts to send/receive data successfully. kStatus_DSPI_Error if driver is error and needs to clean error. kStatus_DSPI_Busy if driver is receiving/transmitting data and not available.
dspi_status_t DSPI_DRV_EdmaSlaveAbortTransfer |
( |
uint32_t |
instance | ) |
|
This function stops the transfer which was started by the DSPI_DRV_EdmaSlaveTransfer() function.
- Parameters
-
instance | The instance number of DSPI peripheral |
- Returns
- kStatus_DSPI_Success if everything is ok. kStatus_DSPI_InvalidMechanism if the current transaction does not use eDMA mechanism.
dspi_status_t DSPI_DRV_EdmaSlaveGetTransferStatus |
( |
uint32_t |
instance, |
|
|
uint32_t * |
framesTransferred |
|
) |
| |
When performing an a-sync transfer, the user can call this function to ascertain the state of the current transfer: in progress (or busy) or complete (success). In addition, if the transfer is still in progress, the user can get the number of words that have been transferred up to now.
- Parameters
-
instance | The instance number of the DSPI peripheral. |
framesTransferred | Pointer to value that is filled in with the number of frames that have been sent in the active transfer. A frame is defined as the number of bits per frame. |
- Returns
- kStatus_DSPI_Success The transfer has completed successfully, or kStatus_DSPI_Busy The transfer is still in progress. framesTransferred is filled with the number of words that have been transferred so far.
void DSPI_DRV_EdmaSlaveIRQHandler |
( |
uint32_t |
instance | ) |
|
This function is DSPI slave interrupt handler using eDMA mechanism. The pupose of this interrupt handler is indicates when the transfer is really finished. The eDMA only used to copy data from/to RX FIFO/TX FIFO, but it not sure the data was transmitted to the master. So must have to enable this interrupt to do it. This interrupt only be enabled when the last four FIFO will be transmitted.
- Parameters
-
This function un-gates the clock to the DSPI module, initializes the DSPI for slave mode. Once initialized, the DSPI module is configured in slave mode and user can start transmit, receive data by calls send, receive, transfer functions. This function indicates DSPI slave will use interrupt mechanism.
- Parameters
-
instance | The instance number of the DSPI peripheral. |
dspiState | The pointer to the DSPI slave driver state structure. |
slaveConfig | The configuration structure dspi_slave_user_config_t which configures the data bus format. |
- Returns
- An error code or kStatus_DSPI_Success.
Disables the DSPI module, gates its clock, change DSPI slave driver state to NonInit for DSPI slave module which is initialized with interrupt mechanism. After de-initialized, user can re-initialize DSPI slave module with other mechanisms.
- Parameters
-
instance | The instance number of the DSPI peripheral. |
- Returns
- kStatus_DSPI_Success indicating successful de-initialization or error code
dspi_status_t DSPI_DRV_SlaveTransferBlocking |
( |
uint32_t |
instance, |
|
|
const uint8_t * |
sendBuffer, |
|
|
uint8_t * |
receiveBuffer, |
|
|
uint32_t |
transferByteCount, |
|
|
uint32_t |
timeout |
|
) |
| |
This function check driver status, mechanism and transmit/receive data through SPI bus. If sendBuffer is NULL, the transmit process is ignored, and if receiveBuffer is NULL the receive process is ignored. If both receiveBuffer and sendBuffer are available, both the transmit and the receive progress are processed. If only the receiveBuffer is available, the receive is processed. Otherwise, the transmit is processed. This function only returns when its processes are complete. This function uses an interrupt mechanism.
- Parameters
-
instance | The instance number of DSPI peripheral |
sendBuffer | The pointer to data that user wants to transmit. |
receiveBuffer | The pointer to data that user wants to store received data. |
transferByteCount | The number of bytes to send and receive. |
timeout | The maximum number of milliseconds that function will wait before timed out reached. |
- Returns
- kStatus_DSPI_Success if driver starts to send/receive data successfully. kStatus_DSPI_Error if driver is error and needs to clean error. kStatus_DSPI_Busy if driver is receiving/transmitting data and not available. kStatus_DSPI_Timeout if time out reached while transferring is in progress.
dspi_status_t DSPI_DRV_SlaveTransfer |
( |
uint32_t |
instance, |
|
|
const uint8_t * |
sendBuffer, |
|
|
uint8_t * |
receiveBuffer, |
|
|
uint32_t |
transferByteCount |
|
) |
| |
This function checks the driver status and sets buffer pointers to receive and transmit the SPI data. If the sendBuffer is NULL, the transmit process is ignored. If the receiveBuffer is NULL, the receive process is ignored. If both the receiveBuffer and the sendBuffer are , available the transfer is done when the kDspiTxDone and the kDspiRxDone are set. If only the receiveBuffer is available, the transfer is done when the kDspiRxDone flag is set. Otherwise, the transfer is done when the kDspiTxDone is set. This function uses an interrupt mechanism.
- Parameters
-
instance | The instance number of DSPI peripheral |
sendBuffer | The pointer to data that user wants to transmit. |
receiveBuffer | The pointer to data that user wants to store received data. |
transferByteCount | The number of bytes to send and receive. |
- Returns
- kStatus_DSPI_Success if driver starts to send/receive data successfully. kStatus_DSPI_Error if driver is error and needs to clean error. kStatus_DSPI_Busy if driver is receiving/transmitting data and not available.
This function stops the transfer which started by calling the DSPI_DRV_SlaveTransfer() function.
- Parameters
-
instance | The instance number of DSPI peripheral |
- Returns
- kStatus_DSPI_Success if everything is OK. kStatus_DSPI_InvalidMechanism if the current transaction does not use interrupt mechanism.
dspi_status_t DSPI_DRV_SlaveGetTransferStatus |
( |
uint32_t |
instance, |
|
|
uint32_t * |
framesTransferred |
|
) |
| |
When performing an a-sync transfer, the user can call this function to ascertain the state of the current transfer: in progress (or busy) or complete (success). In addition, if the transfer is still in progress, the user can get the number of words that have been transferred up to now.
- Parameters
-
instance | The instance number of the DSPI peripheral. |
framesTransferred | Pointer to value that is filled in with the number of frames that have been sent in the active transfer. A frame is defined as the number of bits per frame. |
- Returns
- kStatus_DSPI_Success The transfer has completed successfully, or kStatus_DSPI_Busy The transfer is still in progress. framesTransferred is filled with the number of words that have been transferred so far.
void DSPI_DRV_SlaveIRQHandler |
( |
uint32_t |
instance | ) |
|
This handler check errors of driver and it puts data into Tx FIFO, gets data from Rx FIFO whenever data transmitting/received.
- Parameters
-
instance | The instance number of the DSPI peripheral. |
SPI_Type* const g_dspiBase[SPI_INSTANCE_COUNT] |
const IRQn_Type g_dspiIrqId[SPI_INSTANCE_COUNT] |
volatile bool dspi_dma_slave_state_t::isTransferInProgress |
volatile int32_t dspi_dma_slave_state_t::remainingSendByteCount |
volatile int32_t dspi_dma_slave_state_t::remainingReceiveByteCount |
SPI_Type* const g_dspiBase[SPI_INSTANCE_COUNT] |
const IRQn_Type g_dspiIrqId[SPI_INSTANCE_COUNT] |
volatile bool dspi_edma_slave_state_t::isTransferInProgress |
volatile int32_t dspi_edma_slave_state_t::remainingSendByteCount |
volatile int32_t dspi_edma_slave_state_t::remainingReceiveByteCount |
SPI_Type* const g_dspiBase[SPI_INSTANCE_COUNT] |
const IRQn_Type g_dspiIrqId[SPI_INSTANCE_COUNT] |