19.8.5.1.3 Workflow
- Create a module software instance structure for the SPI module to store the SPI driver state while it is in use.
structspi_module spi_master_instance;structspi_module spi_slave_instance;Note: This should never go out of scope as long as the module is in use. In most cases, this should be global. - Create a module software instance structure for DMA resource to store the DMA resource state while it is in use.
structdma_resource example_resource_tx;structdma_resource example_resource_rx;Note: This should never go out of scope as long as the module is in use. In most cases, this should be global. - Create transfer done flag to indication DMA transfer done.
staticvolatilebooltransfer_tx_is_done =false;staticvolatilebooltransfer_rx_is_done =false; - Define the buffer length for TX/RX.
#define BUF_LENGTH 20 - Create buffer to store the data to be transferred.
staticconstuint8_t buffer_tx[BUF_LENGTH] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,};staticuint8_t buffer_rx[BUF_LENGTH]; - Create the SPI module configuration struct, which can be filled out to adjust the configuration of a physical SPI peripheral.
structspi_config config_spi_master;structspi_config config_spi_slave; - Initialize the SPI configuration struct with the module's default values.
spi_get_config_defaults(&config_spi_master);spi_get_config_defaults(&config_spi_slave);Note: This should always be performed before using the configuration struct to ensure that all values are initialized to known default settings. - Alter the SPI settings to configure the physical pinout, baudrate, and other relevant parameters.
config_spi_master.mux_setting = CONF_MASTER_MUX_SETTING;config_spi_slave.mux_setting = CONF_SLAVE_MUX_SETTING; - Configure the SPI module with the desired settings, retrying while the driver is busy until the configuration is stressfully set.
spi_init(&spi_master_instance, CONF_MASTER_SPI_MODULE, &config_spi_master);spi_init(&spi_slave_instance, CONF_SLAVE_SPI_MODULE, &config_spi_slave); - Enable the SPI module.
spi_enable(&spi_master_instance);spi_enable(&spi_slave_instance); - Create the DMA resource configuration structure, which can be filled out to adjust the configuration of a single DMA transfer.
structdma_resource_config tx_config;structdma_resource_config rx_config; - Initialize the DMA resource configuration struct with the module's default values.
dma_get_config_defaults(&tx_config);dma_get_config_defaults(&rx_config);Note: This should always be performed before using the configuration struct to ensure that all values are initialized to known default settings. - Set extra configurations for the DMA resource. It is using peripheral trigger. SERCOM TX empty and RX complete trigger causes a beat transfer in this example.
tx_config.peripheral_trigger = CONF_PERIPHERAL_TRIGGER_TX;tx_config.trigger_action = DMA_TRIGGER_ACTON_BEAT;rx_config.peripheral_trigger = CONF_PERIPHERAL_TRIGGER_RX;rx_config.trigger_action = DMA_TRIGGER_ACTON_BEAT; - Allocate a DMA resource with the configurations.
dma_allocate(tx_resource, &tx_config);dma_allocate(rx_resource, &rx_config); - Create a DMA transfer descriptor configuration structure, which can be filled out to adjust the configuration of a single DMA transfer.
structdma_descriptor_config tx_descriptor_config;structdma_descriptor_config rx_descriptor_config; - Initialize the DMA transfer descriptor configuration struct with the module's default values.
dma_descriptor_get_config_defaults(&tx_descriptor_config);dma_descriptor_get_config_defaults(&rx_descriptor_config);Note: This should always be performed before using the configuration struct to ensure that all values are initialized to known default settings. - Set the specific parameters for a DMA transfer with transfer size, source address, and destination address.
tx_descriptor_config.beat_size = DMA_BEAT_SIZE_BYTE;tx_descriptor_config.dst_increment_enable =false;tx_descriptor_config.block_transfer_count =sizeof(buffer_tx)/sizeof(uint8_t);tx_descriptor_config.source_address = (uint32_t)buffer_tx +sizeof(buffer_tx);tx_descriptor_config.destination_address =(uint32_t)(&spi_master_instance.hw->SPI.DATA.reg);rx_descriptor_config.beat_size = DMA_BEAT_SIZE_BYTE;rx_descriptor_config.src_increment_enable =false;rx_descriptor_config.block_transfer_count =sizeof(buffer_rx)/sizeof(uint8_t);rx_descriptor_config.source_address =(uint32_t)(&spi_slave_instance.hw->SPI.DATA.reg);rx_descriptor_config.destination_address =(uint32_t)buffer_rx +sizeof(buffer_rx); - Create the DMA transfer descriptor.
dma_descriptor_create(tx_descriptor, &tx_descriptor_config);dma_descriptor_create(rx_descriptor, &rx_descriptor_config);
