SPI Master DMA Driver

The serial peripheral interface (SPI) is a DMA serial communication interface.

The SPI Master DMA driver uses the DMA system to transfer data from a memory buffer to the SPI (Memory to Peripheral), and receive data from the SPI to a memory buffer (Peripheral to Memory). User must configure the DMA system driver accordingly. A callback is called when all the data is transfered or received, if it is registered via the spi_m_dma_register_callback function.

Refer SPI Drivers for more detailed SPI basics.

Summary of the API's Functional Features

The API provides functions to:
  • Initialize and deinitialize the driver and associated hardware

  • Register I/O descriptor

  • Enable or disable SPI master

  • Hookup callback handlers on read/write/transfer complete, or error events

  • Read/Write message to/from the slave

Summary of Configuration Options

Below is a list of the main SPI master DMA parameters that can be configured in START. Many of these parameters are used by the spi_m_dma_init function when initializing the driver and underlying hardware. Most of the initial values can be overridden and changed runtime by calling the appropriate API functions.
  • Select SPI DMA TX channel

  • Select SPI DMA RX channel

  • Select character size

  • Set SPI baudrate

  • Which clock source is used

Driver Implementation Description

After the SPI hardware initialization, the spi_m_dma_get_io_descriptor function is needed to register an I/O descriptor. Then use spi_m_dma_register_callback to register a callback function for the RX/TX/transfer, and enable SPI hardware complete. Then, control the slave select (SS) pin and start the read/write operation.

Limitations

The slave select (SS) is not automatically inserted during read/write/transfer. The user must use an I/O to control the devices'SS.

When the DMA channel is only used for receiving data, the transfer channel must be enabled to send dummy data to the slave.

While read/write/transfer is in progress, the data buffer used must be kept unchanged.

Example of Usage

The following shows a simple example of using the SPI master DMA. The SPI master must have been initialized by spi_m_dma_init. This initialization will configure the operation of the SPI master.

The example registers an I/O descriptor and enables the hardware. Then it registers a callback, and finally starts a writing operation.

          /**
           * Example of using SPI_0 to write "Hello World" using the I/O abstraction.
            
           * Since the driver is asynchronous we need to use statically allocated memory for string
           * because driver initiates transfer and then returns before the transmission is completed.
            
           * Once transfer has been completed the tx_cb function will be called.
           */
          static uint8_t example_SPI_0[12] = "Hello World!";
          static void tx_complete_cb_SPI_0(struct _dma_resource *resource)
          {
              /* Transfer completed */
          }
          void SPI_0_example(void)
          {
              struct io_descriptor *io;
              spi_m_dma_get_io_descriptor(&SPI_0, &io);
              spi_m_dma_register_callback(&SPI_0, SPI_M_DMA_CB_TX_DONE, (FUNC_PTR)tx_complete_cb_SPI_0);
              spi_m_dma_enable(&SPI_0);
              /* Control the slave select (SS) pin */
              //gpio_set_pin_level(SPI_0_SS, false);
              io_write(io, example_SPI_0, 12);
          }
        

Dependencies

  • The SPI master peripheral and its related I/O lines and clocks

  • The NVIC must be configured so that SPI interrupt requests are periodically serviced

  • DMA