Microchip® Advanced Software Framework

Quick Start Guide for SERCOM SPI Master Driver w/ Vectored I/O

This quick start will receive, transmit and transceive bytes on the EXT1 header.

In this use case the SERCOM SPI will be configured with the following settings:

  • 200 kHz SCK
  • SCK, MISO and MOSI on EXT1 header's SPI pins
  • CPOL = 1 and CPHA = 1 (idle SCK high, setup on falling edge, sample on rising)

Setup

Prerequisites

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

Code

Add to the main application source file, outside of any functions:

uint8_t tx_buffer_1[3] = {1, 2, 3};
uint8_t tx_buffer_2[2] = {4, 5};
uint8_t tx_buffer_3[1] = {6};
uint8_t rx_buffer_1[1];
uint8_t rx_buffer_2[2];
{
.length = 3,
},
{
.data = tx_buffer_2,
.length = 2,
},
{
.data = tx_buffer_3,
.length = 1,
},
{
.data = NULL,
.length = 0,
},
};
{
.length = 1,
},
{
.data = NULL,
.length = 2,
},
{
.data = rx_buffer_2,
.length = 2,
},
{
.data = NULL,
.length = 0,
},
};

If not already present, add to the initialization code:

Add to the initialization code:

spi_config.baudrate = 200000;
spi_config.mux_setting = EXT1_SPI_SERCOM_MUX_SETTING;
spi_config.pinmux_pad0 = EXT1_SPI_SERCOM_PINMUX_PAD0;
spi_config.pinmux_pad1 = EXT1_SPI_SERCOM_PINMUX_PAD1;
spi_config.pinmux_pad2 = EXT1_SPI_SERCOM_PINMUX_PAD2;
spi_config.pinmux_pad3 = EXT1_SPI_SERCOM_PINMUX_PAD3;

Workflow

  1. Create data buffers to transfer to/from.
    uint8_t tx_buffer_1[3] = {1, 2, 3};
    uint8_t tx_buffer_2[2] = {4, 5};
    uint8_t tx_buffer_3[1] = {6};
    uint8_t rx_buffer_1[1];
    uint8_t rx_buffer_2[2];
    Note
    These example buffers are in total 6 bytes long for transmit (TX) and 3 bytes long for receive (RX).
  2. Create descriptors for the data buffers. For reception, we will discard two bytes after the first one.
    struct spi_master_vec_bufdesc tx_buffers[4] = {
    {
    .length = 3,
    },
    {
    .data = tx_buffer_2,
    .length = 2,
    },
    {
    .data = tx_buffer_3,
    .length = 1,
    },
    {
    .data = NULL,
    .length = 0,
    },
    };
    struct spi_master_vec_bufdesc rx_buffers[4] = {
    {
    .length = 1,
    },
    {
    .data = NULL,
    .length = 2,
    },
    {
    .data = rx_buffer_2,
    .length = 2,
    },
    {
    .data = NULL,
    .length = 0,
    },
    };
    Attention
    The last descriptor in the array must specify zero length for the driver to know when it has reached the last buffer.
  3. Create an instance of the driver to operate on.

  4. In the initialization code, add a config struct for the driver.

  5. Initialize the config struct and change to the desired configuration.

    spi_config.baudrate = 200000;
    spi_config.mux_setting = EXT1_SPI_SERCOM_MUX_SETTING;
    spi_config.pinmux_pad0 = EXT1_SPI_SERCOM_PINMUX_PAD0;
    spi_config.pinmux_pad1 = EXT1_SPI_SERCOM_PINMUX_PAD1;
    spi_config.pinmux_pad2 = EXT1_SPI_SERCOM_PINMUX_PAD2;
    spi_config.pinmux_pad3 = EXT1_SPI_SERCOM_PINMUX_PAD3;
  6. Initialize the device instance with the configuration and SERCOM to use.

Code

Add to the application code:

while (spi_master_vec_transceive_buffer_job(&spi_master, tx_buffers, rx_buffers) == STATUS_BUSY) {
/* Try to start transfer until it succeeds. */
}

Workflow

  1. Enable the SERCOM module before using it.

  2. Start and wait for first transfer: receive 5 bytes, 3 of which will be written into the RX buffers.

  3. Start transmission of the 6 bytes from TX buffers.

  4. Keep trying to start next transfer until it succeeds: transmit the 6 bytes from the TX buffers and receive 5 bytes, writing 3 of them into the RX buffers simultaneously.

    while (spi_master_vec_transceive_buffer_job(&spi_master, tx_buffers, rx_buffers) == STATUS_BUSY) {
    /* Try to start transfer until it succeeds. */
    }
  5. Wait for transfer to complete.