4.35. SPI
4.35.1. Module Files
4.35.1.1. Driver
- src/app/driver/spi/spi.c
- src/app/driver/spi/spi.h
4.35.1.2. Configuration
- src/app/driver/config/spi_cfg.c
- src/app/driver/config/spi_cfg.h
- src/app/driver/spi/spi_cfg-helper.h
4.35.1.3. Unit Test
- tests/unit/app/driver/spi/test_spi.c
- tests/unit/app/driver/config/test_spi_cfg.c
4.35.2. Description
There are three main functions in the SPI API:
- SPI function to transmit data: used to transmit data without DMA, blocking 
- SPI function to transmit and receive data: used to transmit and receive data without DMA, blocking 
- SPI function to transmit and receive data with DMA: used to transmit and receive data with DMA, non-blocking 
Three other functions are available:
- SPI function to receive data with DMA as a slave device: used to send a dummy byte without DMA, blocking 
- SPI wrapper function for FRAM: wrapper function used in the FRAM module, works without DMA, blocking 
- SPI function to receive data with DMA as a slave device: used to configure an SPI interface as a slave device receiving data over SPI, non blocking. 
 1/**
 2 * @brief   Transmits data on SPI without DMA.
 3 * @details This function can be used to send and receive data via SPI. SPI
 4 *          communication is performed in blocking mode and chip select is
 5 *          set/reset automatically.
 6 * @param   pSpiInterface pointer to SPI interface configuration
 7 * @param   pTxBuff pointer to data that is transmitted by the SPI interface
 8 * @param   frameLength number of bytes to be transmitted by the SPI interface
 9 * @return  status of the SPI transfer
10 */
11extern STD_RETURN_TYPE_e SPI_TransmitData(SPI_INTERFACE_CONFIG_s *pSpiInterface, uint16 *pTxBuff, uint32 frameLength);
 1/**
 2 * @brief   Transmits and receives data on SPI without DMA.
 3 * @details This function can be used to send and receive data via SPI. SPI
 4 *          communication is performed in blocking mode and chip select is
 5 *          set/reset automatically.
 6 * @param   pSpiInterface pointer to SPI interface configuration
 7 * @param   pTxBuff pointer to data that is transmitted by the SPI interface
 8 * @param   pRxBuff pointer to data that is received by the SPI interface
 9 * @param   frameLength number of bytes to be transmitted by the SPI interface
10 * @return  status of the SPI transfer
11 */
12extern STD_RETURN_TYPE_e SPI_TransmitReceiveData(
13    SPI_INTERFACE_CONFIG_s *pSpiInterface,
14    uint16 *pTxBuff,
15    uint16 *pRxBuff,
16    uint32 frameLength);
 1/**
 2 * @brief   Transmits and receives data on SPI with DMA.
 3 * @details This function can be used to send and receive data via SPI. SPI
 4 *          communication is performed in blocking mode and chip select is
 5 *          set/reset automatically..
 6 * @param   pSpiInterface pointer to SPI interface configuration
 7 * @param   pTxBuff pointer to data that is transmitted by the SPI interface
 8 * @param   pRxBuff pointer to data that is received by the SPI interface
 9 * @param   frameLength number of bytes to be transmitted by the SPI interface
10 * @return  status of the SPI transfer
11 */
12extern STD_RETURN_TYPE_e SPI_TransmitReceiveDataDma(
13    SPI_INTERFACE_CONFIG_s *pSpiInterface,
14    uint16_t *pTxBuff,
15    uint16_t *pRxBuff,
16    uint32_t frameLength);
1/**
2 * @brief   Sends a dummy byte to wake up the SPI interface.
3 * @param   pSpiInterface pointer to SPI interface configuration
4 * @param   delay delay to wait after dummy byte transfer
5 * @return  status of the SPI transfer
6 */
7extern STD_RETURN_TYPE_e SPI_TransmitDummyByte(SPI_INTERFACE_CONFIG_s *pSpiInterface, uint32_t delay);
 1/**
 2 * @brief   Transmits and receives data on SPI without DMA, wrapper for FRAM
 3 * @details This function can be used to send and receive data via SPI. SPI
 4 *          communication is performed in blocking mode and chip select is
 5 *          set/reset automatically.
 6 *          It does not drive the Chip Select (neither hardware nor software)
 7 *          as this is done directly in the FRAM functions.
 8 * @param   pSpiInterface pointer to SPI interface configuration
 9 * @param   pTxBuff pointer to data that is transmitted by the SPI interface
10 * @param   pRxBuff pointer to data that is received by the SPI interface
11 * @param   frameLength number of bytes to be transmitted by the SPI interface
12 */
13extern void SPI_FramTransmitReceiveData(
14    SPI_INTERFACE_CONFIG_s *pSpiInterface,
15    uint16 *pTxBuff,
16    uint16 *pRxBuff,
17    uint32 frameLength);
 1/**
 2 * @brief   Transmits and receives data on SPI with DMA.
 3 * @details This function can be used to send and receive data via SPI. SPI
 4 *          communication is performed in blocking mode and chip select is
 5 *          set/reset automatically..
 6 * @param   pSpiInterface pointer to SPI interface configuration
 7 * @param   pTxBuff pointer to data that is transmitted by the SPI interface
 8 * @param   pRxBuff pointer to data that is received by the SPI interface
 9 * @param   frameLength number of bytes to be transmitted by the SPI interface
10 * @return  status of the SPI transfer
11 */
12extern STD_RETURN_TYPE_e SPI_SlaveSetReceiveDataDma(
13    SPI_INTERFACE_CONFIG_s *pSpiInterface,
14    uint16_t *pTxBuff,
15    uint16_t *pRxBuff,
16    uint32_t frameLength);
To configure an SPI interface, a structure of the type Configuration for the SPI interface must be used. One important parameter is the type of the Chip Select pin, to be chosen within the enum Type of Chip Select used. Available possibilities:
- Hardware Chip Select 
- Software Chip Select 
Warning
Currently the DMA functions presented above can only be used with a hardware Chip Select.
1/** configuration of the SPI interface */
2typedef struct {
3    spiDAT1_t *pConfig;
4    spiBASE_t *pNode;
5    volatile uint32_t *pGioPort;
6    uint32_t csPin;
7    SPI_CHIP_SELECT_TYPE_e csType;
8} SPI_INTERFACE_CONFIG_s;
1/** type of chip select for spi */
2typedef enum {
3    SPI_CHIP_SELECT_HARDWARE,
4    SPI_CHIP_SELECT_SOFTWARE,
5    SPI_CHIP_SELECT_MAX,
6} SPI_CHIP_SELECT_TYPE_e;
Warning
The DMA transmit/receive function works only to transmit 3 words and more. To transmit 1 or 2 words, the function without DMA must be used.
The register SPIDAT1 is used to transmit data. It is made out of two bit
groups:
- bits 0 to 15, containing the data to send (up to 16 bits) 
- bits 16 to 31, containing the configuration to be used for the SPI transmission 
When using DMA, only the data group is written, so the configuration is not
taken into account.
This is problematic, as the configuration contains among other the hardware
Chip Select pin to use.
Another issue is that very often SPI transmissions require the Chip Select pin
to be held active.
To realize this, the field CSHOLD in the configuration group must be written
with 1, except for the last word sent, where it must be written with 0.
To overcome these issues, the first word and the last word are written to the
SPIDAT1 register without DMA. This way the configuration group is written
with the first word.
When DMA writes the subsequent words, the configuration group remains
untouched.
When the last word is written, the CSHOLD bit is set to 0.
If this was not done, the Chip Select pin would remains active after the
transmission.
This is the reason why DMA can only be used when transmitting 3 words or more.
