SAM D21 SERCOM SPI Master Configuration
Overview
This page provides a more detailed description of how to configure the SAM D21 SERCOM peripheral into an SPI Master. We cover the key registers to be configured to implement a simple SPI Master application where the SAM D21 reads/writes data to an external serial Flash memory device.
The SPI Master has several configuration possibilities that need to be considered when interfacing with external slave devices.
SPI Transfer Modes
The SPI Master of the SAMD21 supports four data transfer modes. The device that you are communicating with may only support one or two of these modes. You need to refer to the slave device data sheet to determine the supported transfer modes. As an example, the 25AAXXXX/25LCXXXX series of SPI EEPROMs support rising edge-only data per the datasheet:
SCK phase is configured by the Clock Phase bit in the CTRLA register (CTRLA.CPHA). SCK polarity is programmed by the Clock Polarity bit in the CTRLA register (CTRLA.CPOL).
Control of the SS line
A second configuration option to consider is the control of the SS line. The SERCOM module configured as SPI Master can control the SS line or you can define and configure the SS under software control. There are benefits to each option. One instance of controlling the SS from software arises when a slave is expecting the SS to remain low between bytes. As an example of this type of slave operation, the DOGS102-6 LCD has commands that require the SS to be held low between individual transactions. This behavior is achieved by controlling the SS with software. With hardware control, the SS pin will always be driven high for a minimum of one baud cycle between frames:
A master with multiple slaves in parallel MUST control each SS via software:
A master with multiple slaves in series can chose either software or hardware control of SS:
Configuration Steps
The following instructions should be used when configuring the SERCOM peripheral to work as an SPI Master. This section explores a simple and basic configuration, where the SAM D21 is connected to a serial Flash memory:
This application uses:
- SERCOM5 in SPI Master mode
- PB23 (SCK), PB22 (MOSI), PB16 (MISO)
- PA13 (Software-driven SS line)
More advanced applications might use extra functionalities from the peripheral, but the basic principle remains the same.
Here is a high-level step list to configure the peripheral:
- Configure the pins to work as SERCOM I/Os using the PMUX
- Provide a bus clock to the SERCOM peripheral using the Power Manager
- Provide a generic clock to the SERCOM peripheral using GCLK
- Configure the SERCOM SPI control registers for SPI Master operation
Configure the SERCOM5 SPI Pins Using the PMUX
Use the “I/O Multiplexing and Considerations” section of the datasheet to determine what pins can be used and for which SERCOM. The SERCOM operating in Master SPI mode requires four pins to be configured as shown in Table-27-2 from the SAMD21 family datasheet:
MSSEN = 1 is hardware control. Our configuration example uses MSSEN=0 or software control of SS.
The PMUX configuration for alternate pin functions can be found in the “I/O Multiplexing and Considerations” section of the datasheet of the device being targeted. The pins used in this example and their function selection are outlined in red as follows.
- PA13 – software controlled slave select line setup as a GPIO
- PB16 uses SERCOM5/PAD[0] for MISO operation
- PB22 uses SERCOM5/PAD[2] for MOSI operation
- PB23 uses SERCOM5/PAD[3] for SCK operation
The PMUX configuration of the SCK, MOSI and MISO pins is as follows:
- PB16 is configured to use the C alternate function designation (outlined in GREEN above)
- PB22/PB23 are configured to use the D alternate function designation (outlined in GREEN above)
The following is a code sample that performs these assignments:
Finally, we configure PA13 GPIO for the SS function:
#define GPIO_MAP_SS PORT_PA13 // PA13 bit position macro (1<<13)
// Pre-setting Slave Select (SS) high
PORT->Group[GPIO_GROUP_SS].OUTSET.reg = GPIO_MAP_SS;
// Setting SPI Slave Select as an output
PORT->Group[GPIO_GROUP_SS].DIRSET.reg = GPIO_MAP_SS;
Provide a Bus Clock to the SERCOM Peripheral Using the Power Manager
The SERCOM peripheral is implemented on the Advanced Peripheral Bus Clock (APBC). To communicate with the register set, we enable the synchronous clock to the peripheral using the Power Manager (PM) register set. Here is a code example for enabling SERCOM5:
Provide a Generic Clock to the SERCOM Peripheral Using GCLK
The following is an example of SERCOM5 being configured to use Generic Clock source 0 (GCLK 0 - same clock source as used for the CPU):
GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);
Configure the SERCOM SPI control registers for SPI Master operation
The following registers are enable-protected, meaning that they can only be written when the SPI is disabled (i.e., CTRL.ENABLE=0):
- Control A register CTRLA, except Enable CTRLA.ENABLE and Software Reset CTRLA.SWRST
- Control B register CTRLB, except Receiver Enable CTRLB.RXEN
- Baud register BAUD
The following code example disables the SERCOM SPI to allow the configuration of the registers:
SERCOM5->SPI.CTRLA.bit.ENABLE = 0;
Select SERCOM SPI Master Mode Input/Output PADs
The combined configuration of PORT, the Data In Pinout (DIPO) and the Data Out Pinout (DOPO) bit groups in the Control A register (CTRLA.DIPO and CTRLA.DOPO) define the physical position of the SPI signals.
In this application, the default settings are being used. The exception is the DOPO setting and this needs to be set to PAD[2] and PAD [3] as the SPI data out pins:
The following code sample performs this setting:
// DOPO is set to PAD[2,3]
SPI_SERCOM->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE_SPI_MASTER|
SERCOM_SPI_CTRLA_DOPO(1);
BAUD Rate Setting
This is based on desired baud and the asynchronous (GCLK) clock source provided to the SERCOM:
For our example, we are configuring a 50 kHz baud clock, derived from an 8 MHz GCLK source. The following code example performs this initialization:
#define SPI_BAUD 50000
// Calculate BAUD value
uint16_t BAUD_REG = ((float)SPI_CLK_FREQ / (float)(2 * SPI_BAUD)) - 1;
// Set the SPI baud rate
SPI_SERCOM->SPI.BAUD.reg = SERCOM_SPI_BAUD_BAUD(BAUD_REG);
// Enable the Sercom SPI
SPI_SERCOM->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;
// What for synchronization of SERCOM SPI registersbwtween the clock domains
while(SPI_SERCOM->SPI.SYNCBUSY.bit.ENABLE);
After all the steps of this configuration are done, the system is ready to transmit commands/data to the serial Flash device. Visit the SAM D21 SERCOM SPI Master Example Project page to see the complete working demo.