SAM C21 SERCOM SPI Slave Configuration

Last modified by Microchip on 2023/11/09 09:01


This page provides a more detailed description of how to configure the SAM C21 SERCOM peripheral into an SPI Slave. It will cover the key registers to be configured to implement a simple SPI Slave application where the SAM C21 accepts and responds to SPI commands sent by an SPI Host Application running on a PC.

The SPI Slave has several configuration possibilities that need to be considered when interfacing to external SPI Master devices.

Data Transfer Modes

The SPI Slave of the SAM C21 supports all four data transfer modes.

SPI Transfer Modes table

SPI Transfer Modes figure

SPI Transfer Modes figure 2

Module Block Diagram (SPI Slave)

Module Block Diagram (SPI Slave)

Back to top.

Data Interface

There is only a single register interface for the SERCOM in SPI Slave mode, the DATA register. The block diagram above shows these as two separate paths but they share a common register address.

Data to be transmitted by the SPI Slave is written to the DATA register.

Data to be received by the SPI Slave is read from the DATA register.

Back to top.

Clock Interface

The external clock provided via the SCK pin function provides the necessary module clocks. There is no need to configure the BAUD register in SPI Slave mode.

Back to top.

Slave Select (SS) Operation

Per the previous diagrams, an SPI transaction is started with the SS line being asserted by the Master. This detection is automatically detected by the SERCOM module. However, there is an option to allow the device to be woken up when the SS line is asserted by enabling the CTRLB.SSDE bit.

Back to top.


In SPI Slave mode, there are five interrupt sources:

Data Register Empty (DRE)Set when the DATA register is empty
NOTE — flag is cleared by writing to the DATA register
Transmission Complete (TXC)Set when a rising edge is detected on SS
Reception Complete (RXC)Set when unread data is in the DATA register
NOTE — flag is cleared by reading the DATA register
Slave Select Low (SSL)Set when a falling edge is detected on SS
Error (ERR)Set when an error is detected — the only error in SPI Slave mode is the buffer overflow, found at the STATUS.BUFOVF

Back to top.

Addressing Modes

In SPI Slave mode, there are three optional slave addressing modes. These modes work by performing the desired address comparison on the first data byte received by the SERCOM module after SS is asserted.

Enabling Addressing is selected via the CTRLA.FORM register bits.

The desired addressing mode is selected by the CTRLB.AMODE register bits.

MaskADDRMASK[n] removes bit n from the address mask comparison
2 AddressesADDRMASK contains the first match address
ADDR contains the second match address
Address RangeADDRMASK contains the lower limit of the address range
ADDR contains the higher limit of the address range
NOTE — Address ranges are inclusive of the ADDRMASK and ADDR register values

Address with mask figure

Two unique address figure

Addressing range figure

Back to top.

Configuration Steps

Use the following instructions when configuring the SERCOM peripheral to work as an SPI Slave. This section explores a simple and basic configuration, where the SAM C21 is connected as an SPI Slave to an MCP2210 SPI Master device, which issues commands from a PC Terminal Application.

SPI slave demo connection diagram

This application uses:

  • SERCOM5 in SPI Slave mode, with Address Range slave addressing mode enabled
  • PB01 (SCK), PB00 (MOSI), PB02 (MISO), PB03 (SS)

More advanced applications might use extra functionalities from the peripheral, but the basic principle remains the same.

Below is a high-level step list to configure the peripheral:

  1. Configure the SERCOM pins using the PMUX
  2. Provide a Bus Clock to the peripheral using MCLK
  3. Provide a Generic Clock to the peripheral using GCLK
  4. Configure the SERCOM SPI control registers for SPI Slave operation
  5. Configure Interrupts
  6. Enable Module

Back to top.

1. Configure the SERCOM Pins Using the PMUX

Use the “I/O Multiplexing and Considerations” section of the SAM C21 Family datasheetto determine what pins can be used and for which SERCOM. For the example application that follows this page, PB00, PB01, PB02 and PB03 are used, along with SERCOM5.

For the configuration selected above, PB00, PB01, PB02, and PB03 PMUX functionality must be configured to use setting D, from the datasheet PMUX table section, as shown:

PORT function multiplexing for SAM C21 E/G/J

The following is a code example which performs this assignment:

#define PORTB (1ul)
#define SPI_SCK_PIN 1
#define SPI_MOSI_PIN 0
#define SPI_MISO_PIN 2
#define SPI_nSS_PIN 3

//    SPI-MOSI
//    PB00 (SERCOM5-PAD2)
PORT->Group[PORTB].PMUX[0].bit.PMUXE                 = GPIO_PIN_FUNCTION_D;
PORT->Group[PORTB].DIRCLR.reg                        = (0x00000001 << SPI_MOSI_PIN);

//    SPI-CLK
//    PB01 (SERCOM5-PAD3)
PORT->Group[PORTB].PMUX[0].bit.PMUXO                 = GPIO_PIN_FUNCTION_D;
PORT->Group[PORTB].DIRCLR.reg                        = (0x00000001 << SPI_SCK_PIN);

//    SPI-MISO
//    PB02 (SERCOM5-PAD0)
PORT->Group[PORTB].PMUX[1].bit.PMUXE                 = GPIO_PIN_FUNCTION_D;
PORT->Group[PORTB].DIRSET.reg                        = (0x00000001 << SPI_MISO_PIN);

//    SPI-nSS
//    PB03 (SERCOM5-PAD1)
PORT->Group[PORTB].PMUX[1].bit.PMUXO                 = GPIO_PIN_FUNCTION_D;
PORT->Group[PORTB].DIRCLR.reg                        = (0x00000001 << SPI_nSS_PIN);

Note: In addition to configuring the PORT registers, the SERCOM module must also correctly assign the PADS to the SPI input and output pin functions in the SERCOM control registers. For SPI Slave, CTRLA.DIPO is used to assign the MOSI pin location and CTRL.DOPO is used to assign the MISO, SCK and SS pin locations:


If these are not configured correctly, the module will not operate properly with the pins assigned. See Step 4 below for a code example that initializes these bit-fields.

Back to top.

2. Provide a Bus Clock to the Peripheral Using MCLK

The SERCOM peripheral is implemented on the Advanced Peripheral Bus C (APBC). To communicate with the register set, we enable the synchronous clock to the peripheral using the Main Clock Controller (MCLK) register set.

Here is a code example for enabling the bus clock for SERCOM5:

MCLK->APBCMASK.reg |= MCLK_APBCMASK_SERCOM5;        //enable SERCOM5 bus clock

Back to top.

3. Provide a Generic Clock to the Peripheral Using GCLK

The Generic Clock for a peripheral must be configured by writing to the respective Peripheral Channel Control register PCHCTRLm. The Generator used as the source for the Peripheral Clock must be written to the GEN bit field in the Peripheral Channel Control register PCHCTRLm.GEN.

For SERCOM5, there are two clock input selections, a Main clock and a Slow clock. Table 16-9 in the SAM C21 datasheet outlines the PCHCTRLm register-to-peripheral-channel mapping as shown:

PCHCTRLm mapping table

The following code snippet assigns the GCLK to these peripheral channels:


Each SERCOM module has two clock input selections, a Main clock and a Slow clock. Only the Main clock needs to be assigned for SPI Slave operation.

Back to top.

4. Configure the SERCOM SPI Control Registers for SPI Slave Operation

The following code example enables SPI Slave mode operation, with Address Range addressing mode enabled (addresses between 0x01 and 0x07 will be detected). 8-bit data size is selected, and the SERCOM PADS are assigned to the appropriate SPI pin functions via CTRLA.DIPO and CTRLA.DOPO bit-fields:

SERCOM5->SPI.DBGCTRL.reg              = 0;
SERCOM5->SPI.ADDR.bit.ADDR            = 0x07;                // High address limit
SERCOM5->SPI.ADDR.bit.ADDRMASK        = 0x01;                // Low address limit
SERCOM5->SPI.BAUD.reg                 = 0x00;

                       | SERCOM_SPI_CTRLB_AMODE(2)      // Address Range addressing mode
                       | SERCOM_SPI_CTRLB_SSDE
                       | SERCOM_SPI_CTRLB_CHSIZE(0);    // 8-bit data


                       | SERCOM_SPI_CTRLA_DOPO(3)        // SERCOM5 Data Out Pinout
                       | SERCOM_SPI_CTRLA_DIPO(2)        // SERCOM5 Data In Pinout
                       | SERCOM_SPI_CTRLA_FORM(2)        // Format: SPI frame with address
                       | SERCOM_SPI_CTRLA_MODE(2);       // SPI Slave mode operation
                                                         // Do not enable module yet


Note that the module is not enabled until interrupts are configured.

Back to top.

5. Configure Interrupts

For this example application, the following SPI interrupts will be enabled:


The following code example enables these interrupt sources, and set the interrupt priority level to "3" (lowest priority):

                           | SERCOM_SPI_INTFLAG_RXC
                           | SERCOM_SPI_INTFLAG_SSL
                           | SERCOM_SPI_INTFLAG_ERROR;    // clear all flags

                           | SERCOM_SPI_INTFLAG_RXC
                           | SERCOM_SPI_INTFLAG_SSL
                           | SERCOM_SPI_INTFLAG_ERROR;    // enable interrupts

NVIC_SetPriority(SERCOM5_IRQn, 3);        // set priority
NVIC_EnableIRQ(SERCOM5_IRQn);            // enable SERCOM5 NVIC interrupt line

Back to top.

6. Enable Module

Finally, we enable the module:


After all the steps of this configuration are done, the system is ready to receive commands/data. Visit the "SAM C21 SERCOM SPI Slave Example Project" page to see the complete working demo.

Back to top.

Learn More

Back to top.