19.8.5.1.2 Code
Add to the main application source file, before user definitions and functions according to your board:
For SAM D21 Xplained Pro:
#define CONF_MASTER_SPI_MODULE EXT2_SPI_MODULE#define CONF_MASTER_SS_PIN EXT2_PIN_SPI_SS_0#define CONF_MASTER_MUX_SETTING EXT2_SPI_SERCOM_MUX_SETTING#define CONF_MASTER_PINMUX_PAD0 EXT2_SPI_SERCOM_PINMUX_PAD0#define CONF_MASTER_PINMUX_PAD1 PINMUX_UNUSED#define CONF_MASTER_PINMUX_PAD2 EXT2_SPI_SERCOM_PINMUX_PAD2#define CONF_MASTER_PINMUX_PAD3 EXT2_SPI_SERCOM_PINMUX_PAD3
#define CONF_SLAVE_SPI_MODULE EXT1_SPI_MODULE#define CONF_SLAVE_MUX_SETTING EXT1_SPI_SERCOM_MUX_SETTING#define CONF_SLAVE_PINMUX_PAD0 EXT1_SPI_SERCOM_PINMUX_PAD0#define CONF_SLAVE_PINMUX_PAD1 EXT1_SPI_SERCOM_PINMUX_PAD1#define CONF_SLAVE_PINMUX_PAD2 EXT1_SPI_SERCOM_PINMUX_PAD2#define CONF_SLAVE_PINMUX_PAD3 EXT1_SPI_SERCOM_PINMUX_PAD3
For SAM R21 Xplained Pro:#define CONF_PERIPHERAL_TRIGGER_TX SERCOM1_DMAC_ID_TX#define CONF_PERIPHERAL_TRIGGER_RX SERCOM0_DMAC_ID_RX
#define CONF_MASTER_SPI_MODULE SERCOM3#define CONF_MASTER_SS_PIN EXT1_PIN_10#define CONF_MASTER_MUX_SETTING SPI_SIGNAL_MUX_SETTING_E#define CONF_MASTER_PINMUX_PAD0 PINMUX_PA22C_SERCOM3_PAD0#define CONF_MASTER_PINMUX_PAD1 PINMUX_UNUSED#define CONF_MASTER_PINMUX_PAD2 PINMUX_PA18D_SERCOM3_PAD2#define CONF_MASTER_PINMUX_PAD3 PINMUX_PA19D_SERCOM3_PAD3
#define CONF_SLAVE_SPI_MODULE EXT1_SPI_MODULE#define CONF_SLAVE_MUX_SETTING EXT1_SPI_SERCOM_MUX_SETTING#define CONF_SLAVE_PINMUX_PAD0 EXT1_SPI_SERCOM_PINMUX_PAD0#define CONF_SLAVE_PINMUX_PAD1 EXT1_SPI_SERCOM_PINMUX_PAD1#define CONF_SLAVE_PINMUX_PAD2 EXT1_SPI_SERCOM_PINMUX_PAD2#define CONF_SLAVE_PINMUX_PAD3 EXT1_SPI_SERCOM_PINMUX_PAD3
For SAM L21 Xplained Pro:#define CONF_PERIPHERAL_TRIGGER_TX SERCOM3_DMAC_ID_TX#define CONF_PERIPHERAL_TRIGGER_RX SERCOM5_DMAC_ID_RX
#define CONF_MASTER_SPI_MODULE SERCOM2#define CONF_MASTER_SS_PIN EXT1_PIN_12#define CONF_MASTER_MUX_SETTING SPI_SIGNAL_MUX_SETTING_E#define CONF_MASTER_PINMUX_PAD0 PINMUX_PA08D_SERCOM2_PAD0#define CONF_MASTER_PINMUX_PAD1 PINMUX_UNUSED#define CONF_MASTER_PINMUX_PAD2 PINMUX_PA10D_SERCOM2_PAD2#define CONF_MASTER_PINMUX_PAD3 PINMUX_PA11D_SERCOM2_PAD3
#define CONF_SLAVE_SPI_MODULE EXT1_SPI_MODULE#define CONF_SLAVE_MUX_SETTING EXT1_SPI_SERCOM_MUX_SETTING#define CONF_SLAVE_PINMUX_PAD0 EXT1_SPI_SERCOM_PINMUX_PAD0#define CONF_SLAVE_PINMUX_PAD1 EXT1_SPI_SERCOM_PINMUX_PAD1#define CONF_SLAVE_PINMUX_PAD2 EXT1_SPI_SERCOM_PINMUX_PAD2#define CONF_SLAVE_PINMUX_PAD3 EXT1_SPI_SERCOM_PINMUX_PAD3
For SAM L22 Xplained Pro:#define CONF_PERIPHERAL_TRIGGER_TX SERCOM2_DMAC_ID_TX#define CONF_PERIPHERAL_TRIGGER_RX SERCOM0_DMAC_ID_RX
#define CONF_MASTER_SPI_MODULE EXT2_SPI_MODULE#define CONF_MASTER_SS_PIN EXT2_PIN_SPI_SS_0#define CONF_MASTER_MUX_SETTING EXT2_SPI_SERCOM_MUX_SETTING#define CONF_MASTER_PINMUX_PAD0 EXT2_SPI_SERCOM_PINMUX_PAD0#define CONF_MASTER_PINMUX_PAD1 PINMUX_UNUSED#define CONF_MASTER_PINMUX_PAD2 EXT2_SPI_SERCOM_PINMUX_PAD2#define CONF_MASTER_PINMUX_PAD3 EXT2_SPI_SERCOM_PINMUX_PAD3
#define CONF_SLAVE_SPI_MODULE EXT1_SPI_MODULE#define CONF_SLAVE_MUX_SETTING EXT1_SPI_SERCOM_MUX_SETTING#define CONF_SLAVE_PINMUX_PAD0 EXT1_SPI_SERCOM_PINMUX_PAD0#define CONF_SLAVE_PINMUX_PAD1 EXT1_SPI_SERCOM_PINMUX_PAD1#define CONF_SLAVE_PINMUX_PAD2 EXT1_SPI_SERCOM_PINMUX_PAD2#define CONF_SLAVE_PINMUX_PAD3 EXT1_SPI_SERCOM_PINMUX_PAD3
For SAM DA1 Xplained Pro:#define CONF_PERIPHERAL_TRIGGER_TX EXT2_SPI_SERCOM_DMAC_ID_TX#define CONF_PERIPHERAL_TRIGGER_RX EXT1_SPI_SERCOM_DMAC_ID_RX
#define CONF_MASTER_SPI_MODULE EXT2_SPI_MODULE#define CONF_MASTER_SS_PIN EXT2_PIN_SPI_SS_0#define CONF_MASTER_MUX_SETTING EXT2_SPI_SERCOM_MUX_SETTING#define CONF_MASTER_PINMUX_PAD0 EXT2_SPI_SERCOM_PINMUX_PAD0#define CONF_MASTER_PINMUX_PAD1 PINMUX_UNUSED#define CONF_MASTER_PINMUX_PAD2 EXT2_SPI_SERCOM_PINMUX_PAD2#define CONF_MASTER_PINMUX_PAD3 EXT2_SPI_SERCOM_PINMUX_PAD3
#define CONF_SLAVE_SPI_MODULE EXT1_SPI_MODULE#define CONF_SLAVE_MUX_SETTING EXT1_SPI_SERCOM_MUX_SETTING#define CONF_SLAVE_PINMUX_PAD0 EXT1_SPI_SERCOM_PINMUX_PAD0#define CONF_SLAVE_PINMUX_PAD1 EXT1_SPI_SERCOM_PINMUX_PAD1#define CONF_SLAVE_PINMUX_PAD2 EXT1_SPI_SERCOM_PINMUX_PAD2#define CONF_SLAVE_PINMUX_PAD3 EXT1_SPI_SERCOM_PINMUX_PAD3
For SAM C21 Xplained Pro:#define CONF_PERIPHERAL_TRIGGER_TX SERCOM1_DMAC_ID_TX#define CONF_PERIPHERAL_TRIGGER_RX SERCOM0_DMAC_ID_RX
#define CONF_MASTER_SPI_MODULE EXT2_SPI_MODULE#define CONF_MASTER_SS_PIN EXT2_PIN_SPI_SS_0#define CONF_MASTER_MUX_SETTING EXT2_SPI_SERCOM_MUX_SETTING#define CONF_MASTER_PINMUX_PAD0 EXT2_SPI_SERCOM_PINMUX_PAD0#define CONF_MASTER_PINMUX_PAD1 PINMUX_UNUSED#define CONF_MASTER_PINMUX_PAD2 EXT2_SPI_SERCOM_PINMUX_PAD2#define CONF_MASTER_PINMUX_PAD3 EXT2_SPI_SERCOM_PINMUX_PAD3
#define CONF_SLAVE_SPI_MODULE EXT1_SPI_MODULE#define CONF_SLAVE_MUX_SETTING EXT1_SPI_SERCOM_MUX_SETTING#define CONF_SLAVE_PINMUX_PAD0 EXT1_SPI_SERCOM_PINMUX_PAD0#define CONF_SLAVE_PINMUX_PAD1 EXT1_SPI_SERCOM_PINMUX_PAD1#define CONF_SLAVE_PINMUX_PAD2 EXT1_SPI_SERCOM_PINMUX_PAD2#define CONF_SLAVE_PINMUX_PAD3 EXT1_SPI_SERCOM_PINMUX_PAD3
Add to the main application source file, outside of any functions:#define CONF_PERIPHERAL_TRIGGER_TX SERCOM5_DMAC_ID_TX#define CONF_PERIPHERAL_TRIGGER_RX SERCOM1_DMAC_ID_RX
#define BUF_LENGTH 20
#define TEST_SPI_BAUDRATE 1000000UL
#define SLAVE_SELECT_PIN CONF_MASTER_SS_PIN
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];
structspi_module spi_master_instance;structspi_module spi_slave_instance;
staticvolatilebooltransfer_tx_is_done =false;staticvolatilebooltransfer_rx_is_done =false;
structspi_slave_inst slave;
Copy-paste the following setup code to your user application:COMPILER_ALIGNED(16)DmacDescriptor example_descriptor_tx;DmacDescriptor example_descriptor_rx;
Add to user application initialization (typically the start of main()):staticvoidtransfer_tx_done(structdma_resource*constresource ){transfer_tx_is_done =true;}staticvoidtransfer_rx_done(structdma_resource*constresource ){transfer_rx_is_done =true;}staticvoidconfigure_dma_resource_tx(structdma_resource *tx_resource){structdma_resource_config tx_config;dma_get_config_defaults(&tx_config);tx_config.peripheral_trigger = CONF_PERIPHERAL_TRIGGER_TX;tx_config.trigger_action = DMA_TRIGGER_ACTON_BEAT;dma_allocate(tx_resource, &tx_config);}staticvoidconfigure_dma_resource_rx(structdma_resource *rx_resource){structdma_resource_config rx_config;dma_get_config_defaults(&rx_config);rx_config.peripheral_trigger = CONF_PERIPHERAL_TRIGGER_RX;rx_config.trigger_action = DMA_TRIGGER_ACTON_BEAT;dma_allocate(rx_resource, &rx_config);}staticvoidsetup_transfer_descriptor_tx(DmacDescriptor *tx_descriptor){structdma_descriptor_config tx_descriptor_config;dma_descriptor_get_config_defaults(&tx_descriptor_config);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);dma_descriptor_create(tx_descriptor, &tx_descriptor_config);}staticvoidsetup_transfer_descriptor_rx(DmacDescriptor *rx_descriptor){structdma_descriptor_config rx_descriptor_config;dma_descriptor_get_config_defaults(&rx_descriptor_config);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);dma_descriptor_create(rx_descriptor, &rx_descriptor_config);}staticvoidconfigure_spi_master(void){structspi_config config_spi_master;structspi_slave_inst_config slave_dev_config;/* Configure and initialize software device instance of peripheral slave */spi_slave_inst_get_config_defaults(&slave_dev_config);slave_dev_config.ss_pin = SLAVE_SELECT_PIN;spi_attach_slave(&slave, &slave_dev_config);/* Configure, initialize and enable SERCOM SPI module */spi_get_config_defaults(&config_spi_master);config_spi_master.mode_specific.master.baudrate = TEST_SPI_BAUDRATE;config_spi_master.mux_setting = CONF_MASTER_MUX_SETTING;/* Configure pad 0 for data in */config_spi_master.pinmux_pad0 = CONF_MASTER_PINMUX_PAD0;/* Configure pad 1 as unused */config_spi_master.pinmux_pad1 = CONF_MASTER_PINMUX_PAD1;/* Configure pad 2 for data out */config_spi_master.pinmux_pad2 = CONF_MASTER_PINMUX_PAD2;/* Configure pad 3 for SCK */config_spi_master.pinmux_pad3 = CONF_MASTER_PINMUX_PAD3;spi_init(&spi_master_instance, CONF_MASTER_SPI_MODULE, &config_spi_master);spi_enable(&spi_master_instance);}staticvoidconfigure_spi_slave(void){structspi_config config_spi_slave;/* Configure, initialize and enable SERCOM SPI module */spi_get_config_defaults(&config_spi_slave);config_spi_slave.mode = SPI_MODE_SLAVE;config_spi_slave.mode_specific.slave.preload_enable =true;config_spi_slave.mode_specific.slave.frame_format = SPI_FRAME_FORMAT_SPI_FRAME;config_spi_slave.mux_setting = CONF_SLAVE_MUX_SETTING;/* Configure pad 0 for data in */config_spi_slave.pinmux_pad0 = CONF_SLAVE_PINMUX_PAD0;/* Configure pad 1 as unused */config_spi_slave.pinmux_pad1 = CONF_SLAVE_PINMUX_PAD1;/* Configure pad 2 for data out */config_spi_slave.pinmux_pad2 = CONF_SLAVE_PINMUX_PAD2;/* Configure pad 3 for SCK */config_spi_slave.pinmux_pad3 = CONF_SLAVE_PINMUX_PAD3;spi_init(&spi_slave_instance, CONF_SLAVE_SPI_MODULE, &config_spi_slave);spi_enable(&spi_slave_instance);}
configure_spi_master();configure_spi_slave();configure_dma_resource_tx(&example_resource_tx);configure_dma_resource_rx(&example_resource_rx);setup_transfer_descriptor_tx(&example_descriptor_tx);setup_transfer_descriptor_rx(&example_descriptor_rx);dma_add_descriptor(&example_resource_tx, &example_descriptor_tx);dma_add_descriptor(&example_resource_rx, &example_descriptor_rx);dma_register_callback(&example_resource_tx, transfer_tx_done,DMA_CALLBACK_TRANSFER_DONE);dma_register_callback(&example_resource_rx, transfer_rx_done,DMA_CALLBACK_TRANSFER_DONE);dma_enable_callback(&example_resource_tx, DMA_CALLBACK_TRANSFER_DONE);dma_enable_callback(&example_resource_rx, DMA_CALLBACK_TRANSFER_DONE);
