4.38. SPI

4.38.1. Module Files

4.38.1.1. Driver

  • src/app/driver/spi/spi.c

  • src/app/driver/spi/spi.h

4.38.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.38.1.3. Unit Test

  • tests/unit/app/driver/spi/test_spi.c

  • tests/unit/app/driver/config/test_spi_cfg.c

4.38.2. Description

There are three main functions in the SPI API:

Three other functions are available:

Listing 4.12 SPI function to transmit data
 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);
Listing 4.13 SPI function to transmit and receive data
 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);
Listing 4.14 SPI function to transmit and receive data with DMA
 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);
Listing 4.15 SPI function to receive data with DMA as a slave device
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);
Listing 4.16 SPI wrapper function for FRAM
 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);
Listing 4.17 SPI function to receive data with DMA as a slave device
 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.

Listing 4.18 Configuration for the SPI interface
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;
Listing 4.19 Type of Chip Select used
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.