Microchip® Advanced Software Framework

Quick Start Guide for SERCOM SPI Master - Callback

In this use case, the SPI on extension header 1 of the Xplained Pro board will be configured with the following settings:

  • Master Mode enabled
  • MSB of the data is transmitted first
  • Transfer mode 0
  • SPI MUX Setting E (see Master Mode Settings)
  • 8-bit character size
  • Not enabled in sleep mode
  • Baudrate 100000
  • GLCK generator 0

Setup

Prerequisites

There are no special setup requirements for this use-case.

Code

The following must be added to the user application.

A sample buffer to send via SPI.

static uint8_t wr_buffer[BUF_LENGTH] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13
};
static uint8_t rd_buffer[BUF_LENGTH];

Number of entries in the sample buffer.

#define BUF_LENGTH 20

GPIO pin to use as Slave Select.

#define SLAVE_SELECT_PIN CONF_MASTER_SS_PIN

A globally available software device instance struct to store the SPI driver state while it is in use.

struct spi_module spi_master_instance;

A globally available peripheral slave software device instance struct.

struct spi_slave_inst slave;

A function for configuring the SPI.

void configure_spi_master(void)
{
struct spi_config config_spi_master;
struct spi_slave_inst_config slave_dev_config;
/* Configure and initialize software device instance of peripheral slave */
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.mux_setting = CONF_MASTER_MUX_SETTING;
config_spi_master.pinmux_pad0 = CONF_MASTER_PINMUX_PAD0;
config_spi_master.pinmux_pad1 = CONF_MASTER_PINMUX_PAD1;
config_spi_master.pinmux_pad2 = CONF_MASTER_PINMUX_PAD2;
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);
}

A function for configuring the callback functionality of the SPI.

void configure_spi_master_callbacks(void)
{
spi_register_callback(&spi_master_instance, callback_spi_master,
}

A global variable that can flag to the application that the buffer has been transferred.

volatile bool transrev_complete_spi_master = false;

Callback function.

static void callback_spi_master( struct spi_module *const module)
{
transrev_complete_spi_master = true;
}

Add to user application main().

/* Initialize system */
configure_spi_master();
configure_spi_master_callbacks();

Workflow

  1. Initialize system.
  2. Set-up the SPI.
    configure_spi_master();
    1. Create configuration struct.
      struct spi_config config_spi_master;
    2. Create peripheral slave configuration struct.
      struct spi_slave_inst_config slave_dev_config;
    3. Get default peripheral slave configuration.
    4. Set Slave Select pin.
      slave_dev_config.ss_pin = SLAVE_SELECT_PIN;
    5. Initialize peripheral slave software instance with configuration.
      spi_attach_slave(&slave, &slave_dev_config);
    6. Get default configuration to edit.
      spi_get_config_defaults(&config_spi_master);
    7. Set MUX setting E.
      config_spi_master.mux_setting = CONF_MASTER_MUX_SETTING;
    8. Set pinmux for pad 0 (data in MISO).
    9. Set pinmux for pad 1 as unused, so the pin can be used for other purposes.
    10. Set pinmux for pad 2 (data out MOSI).
    11. Set pinmux for pad 3 (SCK).
    12. Initialize SPI module with configuration.
      spi_init(&spi_master_instance, CONF_MASTER_SPI_MODULE, &config_spi_master);
    13. Enable SPI module.
      spi_enable(&spi_master_instance);
  3. Setup the callback functionality.
    configure_spi_master_callbacks();
    1. Register callback function for buffer transmitted.
      spi_register_callback(&spi_master_instance, callback_spi_master,
    2. Enable callback for buffer transmitted.

Use Case

Code

Add the following to your user application main().

while (true) {
/* Infinite loop */
spi_select_slave(&spi_master_instance, &slave, true);
spi_transceive_buffer_job(&spi_master_instance, wr_buffer,rd_buffer,BUF_LENGTH);
while (!transrev_complete_spi_master) {
}
transrev_complete_spi_master = false;
spi_select_slave(&spi_master_instance, &slave, false);
}
}

Workflow

  1. Select slave.
    spi_select_slave(&spi_master_instance, &slave, true);
  2. Write buffer to SPI slave.
    spi_transceive_buffer_job(&spi_master_instance, wr_buffer,rd_buffer,BUF_LENGTH);
  3. Wait for the transfer to be complete.
    while (!transrev_complete_spi_master) {
    }
    transrev_complete_spi_master = false;
  4. Deselect slave.
    spi_select_slave(&spi_master_instance, &slave, false);
  5. Infinite loop.
    while (true) {
    /* Infinite loop */
    spi_select_slave(&spi_master_instance, &slave, true);
    spi_transceive_buffer_job(&spi_master_instance, wr_buffer,rd_buffer,BUF_LENGTH);
    while (!transrev_complete_spi_master) {
    }
    transrev_complete_spi_master = false;
    spi_select_slave(&spi_master_instance, &slave, false);
    }
    }

Callback

When the buffer is successfully transmitted to the slave, the callback function will be called.

Workflow

  1. Let the application know that the buffer is transmitted by setting the global variable to true.
    transrev_complete_spi_master = true;