Microchip® Advanced Software Framework

Quick Start Guide for SERCOM SPI Slave - Polled

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

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

Setup

Prerequisites

The device must be connected to an SPI master which must read from the device.

Code

The following must be added to the user application source file, outside any functions:

A sample buffer to send via SPI.

static uint8_t buffer_expect[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 buffer_rx[BUF_LENGTH] = {0x00};

Number of entries in the sample buffer.

#define BUF_LENGTH 20

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

struct spi_module spi_slave_instance;

A function for configuring the SPI.

void configure_spi_slave(void)
{
struct spi_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;
config_spi_slave.pinmux_pad0 = CONF_SLAVE_PINMUX_PAD0;
config_spi_slave.pinmux_pad1 = CONF_SLAVE_PINMUX_PAD1;
config_spi_slave.pinmux_pad2 = CONF_SLAVE_PINMUX_PAD2;
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);
}

Add to user application main().

uint8_t result = 0;
/* Initialize system */
configure_spi_slave();

Workflow

  1. Initialize system.
  2. Set-up the SPI.
    configure_spi_slave();
    1. Create configuration struct.
      struct spi_config config_spi_slave;
    2. Get default configuration to edit.
      spi_get_config_defaults(&config_spi_slave);
    3. Set the SPI in slave mode.
      config_spi_slave.mode = SPI_MODE_SLAVE;
    4. Enable preloading of shift register.
      config_spi_slave.mode_specific.slave.preload_enable = true;
    5. Set frame format to SPI frame.
      config_spi_slave.mode_specific.slave.frame_format = SPI_FRAME_FORMAT_SPI_FRAME;
    6. Set MUX setting E.
      config_spi_slave.mux_setting = CONF_SLAVE_MUX_SETTING;
    7. Set pinmux for pad 0 (data in MOSI).
    8. Set pinmux for pad 1 (slave select).
    9. Set pinmux for pad 2 (data out MISO).
    10. Set pinmux for pad 3 (SCK).
    11. Initialize SPI module with configuration.
      spi_init(&spi_slave_instance, CONF_SLAVE_SPI_MODULE, &config_spi_slave);
    12. Enable SPI module.
      spi_enable(&spi_slave_instance);

Use Case

Code

Add the following to your user application main().

while(spi_read_buffer_wait(&spi_slave_instance, buffer_rx, BUF_LENGTH,
0x00) != STATUS_OK) {
/* Wait for transfer from the master */
}
for (uint8_t i = 0; i < BUF_LENGTH; i++) {
if(buffer_rx[i] != buffer_expect[i]) {
result++;
}
}
while (true) {
/* Infinite loop */
if (result) {
/* Add a short delay to see LED toggle */
volatile uint32_t delay = 30000;
while(delay--) {
}
} else {
/* Add a short delay to see LED toggle */
volatile uint32_t delay = 600000;
while(delay--) {
}
}
}

Workflow

  1. Read data from SPI master.
    while(spi_read_buffer_wait(&spi_slave_instance, buffer_rx, BUF_LENGTH,
    0x00) != STATUS_OK) {
    /* Wait for transfer from the master */
    }
  2. Compare the received data with the transmitted data from SPI master.
    for (uint8_t i = 0; i < BUF_LENGTH; i++) {
    if(buffer_rx[i] != buffer_expect[i]) {
    result++;
    }
    }
  3. Infinite loop. If the data is matched, LED0 will flash slowly. Otherwise, LED will flash quickly.
    while (true) {
    /* Infinite loop */
    if (result) {
    /* Add a short delay to see LED toggle */
    volatile uint32_t delay = 30000;
    while(delay--) {
    }
    } else {
    /* Add a short delay to see LED toggle */
    volatile uint32_t delay = 600000;
    while(delay--) {
    }
    }
    }