Microchip® Advanced Software Framework

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
SAM Serial Peripheral Interface (SERCOM SPI) Driver

This driver for Atmel® | SMART ARM®-based microcontrollers provides an interface for the configuration and management of the SERCOM module in its SPI mode to transfer SPI data frames.

The following driver API modes are covered by this manual:

The following peripheral is used by this module:

The following devices can use this module:

The outline of this documentation is as follows:

Prerequisites

There are no prerequisites.

Module Overview

The Serial Peripheral Interface (SPI) is a high-speed synchronous data transfer interface using three or four pins. It allows fast communication between a master device and one or more peripheral devices.

A device connected to the bus must act as a master or a slave. The master initiates and controls all data transactions. The SPI master initiates a communication cycle by pulling low the Slave Select (SS) pin of the desired slave. The Slave Select pin is active low. Master and slave prepare data to be sent in their respective shift registers, and the master generates the required clock pulses on the SCK line to interchange data. Data is always shifted from master to slave on the Master Out - Slave In (MOSI) line, and from slave to master on the Master In - Slave Out (MISO) line. After each data transfer, the master can synchronize to the slave by pulling the SS line high.

Driver Feature Macro Definition

Driver feature macro Supported devices
FEATURE_SPI_SLAVE_SELECT_LOW_DETECT SAM D21/R21/D10/D11/L21/L22/DA1/C20/C21/R30/R34/R35
FEATURE_SPI_HARDWARE_SLAVE_SELECT SAM D21/R21/D10/D11/L21/L22/DA1/C20/C21/R30/R34/R35
FEATURE_SPI_ERROR_INTERRUPT SAM D21/R21/D10/D11/L21/L22/DA1/C20/C21/R30/R34/R35
FEATURE_SPI_SYNC_SCHEME_VERSION_2 SAM D21/R21/D10/D11/L21/L22/DA1/C20/C21/R30/R34/R35
Note
The specific features are only available in the driver when the selected device supports those features.

SPI Bus Connection

In the figure below, the connection between one master and one slave is shown.

The different lines are as follows:

If the bus consists of several SPI slaves, they can be connected in parallel and the SPI master can use general I/O pins to control separate SS lines to each slave on the bus.

It is also possible to connect all slaves in series. In this configuration, a common SS is provided to N slaves, enabling them simultaneously. The MISO from the N-1 slaves is connected to the MOSI on the next slave. The Nth slave connects its MISO back to the master. For a complete transaction, the master must shift N+1 characters.

SPI Character Size

The SPI character size is configurable to eight or nine bits.

Master Mode

When configured as a master, the SS pin will be configured as an output.

Data Transfer

Writing a character will start the SPI clock generator, and the character is transferred to the shift register when the shift register is empty. Once this is done, a new character can be written. As each character is shifted out from the master, a character is shifted in from the slave. If the receiver is enabled, the data is moved to the receive buffer at the completion of the frame and can be read.

Slave Mode

When configured as a slave, the SPI interface will remain inactive with MISO tri-stated as long as the SS pin is driven high.

Data Transfer

The data register can be updated at any time. As the SPI slave shift register is clocked by SCK, a minimum of three SCK cycles are needed from the time new data is written, until the character is ready to be shifted out. If the shift register has not been loaded with data, the current contents will be transmitted.

If constant transmission of data is needed in SPI slave mode, the system clock should be faster than SCK. If the receiver is enabled, the received character can be read from the receive buffer. When SS line is driven high, the slave will not receive any additional data.

Address Recognition

When the SPI slave is configured with address recognition, the first character in a transaction is checked for an address match. If there is a match, the MISO output is enabled and the transaction is processed. If the address does not match, the complete transaction is ignored.

If the device is asleep, it can be woken up by an address match in order to process the transaction.

Note
In master mode, an address packet is written by the spi_select_slave function if the address_enabled configuration is set in the spi_slave_inst_config struct.

Data Modes

There are four combinations of SCK phase and polarity with respect to serial data. The table below shows the clock polarity (CPOL) and clock phase (CPHA) in the different modes. Leading edge is the first clock edge in a clock cycle and trailing edge is the last clock edge in a clock cycle.

SPI Data Modes
Mode CPOL CPHA Leading Edge Trailing Edge
0 0 0 Rising, Sample Falling, Setup
1 0 1 Rising, Setup Falling, Sample
2 1 0 Falling, Sample Rising, Setup
3 1 1 Falling, Setup Rising, Sample

SERCOM Pads

The SERCOM pads are automatically configured as seen in the table below. If the receiver is disabled, the data input (MISO for master, MOSI for slave) can be used for other purposes.

In master mode, the SS pin(s) must be configured using the spi_slave_inst struct.

SERCOM SPI Pad Usages
Pin Master SPI Slave SPI
MOSI Output Input
MISO Input Output
SCK Output Input
SS User defined output enable Input

Operation in Sleep Modes

The SPI module can operate in all sleep modes by setting the run_in_standby option in the spi_config struct. The operation in slave and master mode is shown in the table below.

run_in_standby Slave Master
false Disabled, all reception is dropped GCLK is disabled when master is idle, wake on transmit complete
true Wake on reception GCLK is enabled while in sleep modes, wake on all interrupts

Clock Generation

In SPI master mode, the clock (SCK) is generated internally using the SERCOM baudrate generator. In SPI slave mode, the clock is provided by an external master on the SCK pin. This clock is used to directly clock the SPI shift register.

Special Considerations

pinmux Settings

The pin MUX settings must be configured properly, as not all settings can be used in different modes of operation.

Extra Information

For extra information, see Extra Information for SERCOM SPI Driver. This includes:

Examples

For a list of examples related to this driver, see Examples for SERCOM SPI Driver.

API Overview

Data Structures

struct  spi_config
 SPI configuration structure. More...
 
struct  spi_master_config
 SPI Master configuration structure. More...
 
struct  spi_module
 SERCOM SPI driver software device instance structure. More...
 
struct  spi_slave_config
 SPI slave configuration structure. More...
 
struct  spi_slave_inst
 SPI peripheral slave instance structure. More...
 
struct  spi_slave_inst_config
 SPI peripheral slave configuration structure. More...
 

Macros

#define PINMUX_DEFAULT   0
 Default pinmux. More...
 
#define PINMUX_UNUSED   0xFFFFFFFF
 Unused pinmux. More...
 
#define SPI_TIMEOUT   10000
 SPI timeout value. More...
 

Enumerations

enum  spi_addr_mode {
  SPI_ADDR_MODE_MASK = SERCOM_SPI_CTRLB_AMODE(0),
  SPI_ADDR_MODE_UNIQUE = SERCOM_SPI_CTRLB_AMODE(1),
  SPI_ADDR_MODE_RANGE = SERCOM_SPI_CTRLB_AMODE(2)
}
 SPI address modes enum. More...
 
enum  spi_character_size {
  SPI_CHARACTER_SIZE_8BIT = SERCOM_SPI_CTRLB_CHSIZE(0),
  SPI_CHARACTER_SIZE_9BIT = SERCOM_SPI_CTRLB_CHSIZE(1)
}
 SPI character size enum. More...
 
enum  spi_data_order {
  SPI_DATA_ORDER_LSB = SERCOM_SPI_CTRLA_DORD,
  SPI_DATA_ORDER_MSB = 0
}
 SPI data order enum. More...
 
enum  spi_frame_format {
  SPI_FRAME_FORMAT_SPI_FRAME = SERCOM_SPI_CTRLA_FORM(0),
  SPI_FRAME_FORMAT_SPI_FRAME_ADDR = SERCOM_SPI_CTRLA_FORM(2)
}
 SPI frame format enum. More...
 
enum  spi_interrupt_flag {
  SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY = SERCOM_SPI_INTFLAG_DRE,
  SPI_INTERRUPT_FLAG_TX_COMPLETE = SERCOM_SPI_INTFLAG_TXC,
  SPI_INTERRUPT_FLAG_RX_COMPLETE = SERCOM_SPI_INTFLAG_RXC
}
 SPI Interrupt Flags. More...
 
enum  spi_mode {
  SPI_MODE_MASTER = 1,
  SPI_MODE_SLAVE = 0
}
 SPI modes enum. More...
 
enum  spi_signal_mux_setting {
  SPI_SIGNAL_MUX_SETTING_A,
  SPI_SIGNAL_MUX_SETTING_B,
  SPI_SIGNAL_MUX_SETTING_C,
  SPI_SIGNAL_MUX_SETTING_D,
  SPI_SIGNAL_MUX_SETTING_E,
  SPI_SIGNAL_MUX_SETTING_F,
  SPI_SIGNAL_MUX_SETTING_G,
  SPI_SIGNAL_MUX_SETTING_H,
  SPI_SIGNAL_MUX_SETTING_I,
  SPI_SIGNAL_MUX_SETTING_J,
  SPI_SIGNAL_MUX_SETTING_K,
  SPI_SIGNAL_MUX_SETTING_L,
  SPI_SIGNAL_MUX_SETTING_M,
  SPI_SIGNAL_MUX_SETTING_N,
  SPI_SIGNAL_MUX_SETTING_O,
  SPI_SIGNAL_MUX_SETTING_P
}
 SPI signal MUX settings. More...
 
enum  spi_transfer_mode {
  SPI_TRANSFER_MODE_0 = 0,
  SPI_TRANSFER_MODE_1 = SERCOM_SPI_CTRLA_CPHA,
  SPI_TRANSFER_MODE_2 = SERCOM_SPI_CTRLA_CPOL,
  SPI_TRANSFER_MODE_3 = SERCOM_SPI_CTRLA_CPHA | SERCOM_SPI_CTRLA_CPOL
}
 SPI transfer modes enum. More...
 

Functions

static bool spi_is_syncing (struct spi_module *const module)
 Determines if the SPI module is currently synchronizing to the bus. More...
 
enum status_code spi_set_baudrate (struct spi_module *const module, uint32_t baudrate)
 Set the baudrate of the SPI module. More...
 

Driver Initialization and Configuration

static void spi_get_config_defaults (struct spi_config *const config)
 Initializes an SPI configuration structure to default values. More...
 
static void spi_slave_inst_get_config_defaults (struct spi_slave_inst_config *const config)
 Initializes an SPI peripheral slave device configuration structure to default values. More...
 
static void spi_attach_slave (struct spi_slave_inst *const slave, const struct spi_slave_inst_config *const config)
 Attaches an SPI peripheral slave. More...
 
enum status_code spi_init (struct spi_module *const module, Sercom *const hw, const struct spi_config *const config)
 Initializes the SERCOM SPI module. More...
 

Enable/Disable

static void spi_enable (struct spi_module *const module)
 Enables the SERCOM SPI module. More...
 
static void spi_disable (struct spi_module *const module)
 Disables the SERCOM SPI module. More...
 
void spi_reset (struct spi_module *const module)
 Resets the SPI module. More...
 

Lock/Unlock

static enum status_code spi_lock (struct spi_module *const module)
 Attempt to get lock on driver instance. More...
 
static void spi_unlock (struct spi_module *const module)
 Unlock driver instance. More...
 

Ready to Write/Read

static bool spi_is_write_complete (struct spi_module *const module)
 Checks if the SPI in master mode has shifted out last data, or if the master has ended the transfer in slave mode. More...
 
static bool spi_is_ready_to_write (struct spi_module *const module)
 Checks if the SPI module is ready to write data. More...
 
static bool spi_is_ready_to_read (struct spi_module *const module)
 Checks if the SPI module is ready to read data. More...
 

Read/Write

static enum status_code spi_write (struct spi_module *module, uint16_t tx_data)
 Transfers a single SPI character. More...
 
enum status_code spi_write_buffer_wait (struct spi_module *const module, const uint8_t *tx_data, uint16_t length)
 Sends a buffer of length SPI characters. More...
 
static enum status_code spi_read (struct spi_module *const module, uint16_t *rx_data)
 Reads last received SPI character. More...
 
enum status_code spi_read_buffer_wait (struct spi_module *const module, uint8_t *rx_data, uint16_t length, uint16_t dummy)
 Reads buffer of length SPI characters. More...
 
enum status_code spi_transceive_wait (struct spi_module *const module, uint16_t tx_data, uint16_t *rx_data)
 Sends and reads a single SPI character. More...
 
enum status_code spi_transceive_buffer_wait (struct spi_module *const module, uint8_t *tx_data, uint8_t *rx_data, uint16_t length)
 Sends and receives a buffer of length SPI characters. More...
 
enum status_code spi_select_slave (struct spi_module *const module, struct spi_slave_inst *const slave, bool select)
 Selects slave device. More...
 

#define PINMUX_DEFAULT   0

Default pinmux.

Referenced by spi_get_config_defaults().

#define PINMUX_UNUSED   0xFFFFFFFF

Unused pinmux.

#define SPI_TIMEOUT   10000

SPI address modes enum.

For slave mode when using the SPI frame with address format.

Enumerator
SPI_ADDR_MODE_MASK 

address_mask in the spi_config struct is used as a mask to the register

SPI_ADDR_MODE_UNIQUE 

The slave responds to the two unique addresses in address and address_mask in the spi_config struct.

SPI_ADDR_MODE_RANGE 

The slave responds to the range of addresses between and including address and address_mask in the spi_config struct.

SPI character size enum.

SPI character size.

Enumerator
SPI_CHARACTER_SIZE_8BIT 

8-bit character

SPI_CHARACTER_SIZE_9BIT 

9-bit character

SPI data order enum.

SPI data order.

Enumerator
SPI_DATA_ORDER_LSB 

The LSB of the data is transmitted first.

SPI_DATA_ORDER_MSB 

The MSB of the data is transmitted first.

SPI frame format enum.

Frame format for slave mode.

Enumerator
SPI_FRAME_FORMAT_SPI_FRAME 

SPI frame.

SPI_FRAME_FORMAT_SPI_FRAME_ADDR 

SPI frame with address.

SPI Interrupt Flags.

Interrupt flags for the SPI module.

Enumerator
SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY 

This flag is set when the contents of the data register has been moved to the shift register and the data register is ready for new data.

SPI_INTERRUPT_FLAG_TX_COMPLETE 

This flag is set when the contents of the shift register has been shifted out.

SPI_INTERRUPT_FLAG_RX_COMPLETE 

This flag is set when data has been shifted into the data register.

enum spi_mode

SPI modes enum.

SPI mode selection.

Enumerator
SPI_MODE_MASTER 

Master mode.

SPI_MODE_SLAVE 

Slave mode.

SPI signal MUX settings.

Set the functionality of the SERCOM pins. As not all combinations can be used in different modes of operation, proper combinations must be chosen according to the rest of the configuration.

Note
In master operation: DI is MISO, DO is MOSI. In slave operation: DI is MOSI, DO is MISO.

See MUX Settings for a description of the various MUX setting options.

Enumerator
SPI_SIGNAL_MUX_SETTING_A 

SPI MUX combination A.

DOPO: 0x0, DIPO: 0x0

SPI_SIGNAL_MUX_SETTING_B 

SPI MUX combination B.

DOPO: 0x0, DIPO: 0x1

SPI_SIGNAL_MUX_SETTING_C 

SPI MUX combination C.

DOPO: 0x0, DIPO: 0x2

SPI_SIGNAL_MUX_SETTING_D 

SPI MUX combination D.

DOPO: 0x0, DIPO: 0x3

SPI_SIGNAL_MUX_SETTING_E 

SPI MUX combination E.

DOPO: 0x1, DIPO: 0x0

SPI_SIGNAL_MUX_SETTING_F 

SPI MUX combination F.

DOPO: 0x1, DIPO: 0x1

SPI_SIGNAL_MUX_SETTING_G 

SPI MUX combination G.

DOPO: 0x1, DIPO: 0x2

SPI_SIGNAL_MUX_SETTING_H 

SPI MUX combination H.

DOPO: 0x1, DIPO: 0x3

SPI_SIGNAL_MUX_SETTING_I 

SPI MUX combination I.

DOPO: 0x2, DIPO: 0x0

SPI_SIGNAL_MUX_SETTING_J 

SPI MUX combination J.

DOPO: 0x2, DIPO: 0x1

SPI_SIGNAL_MUX_SETTING_K 

SPI MUX combination K.

DOPO: 0x2, DIPO: 0x2

SPI_SIGNAL_MUX_SETTING_L 

SPI MUX combination L.

DOPO: 0x2, DIPO: 0x3

SPI_SIGNAL_MUX_SETTING_M 

SPI MUX combination M.

DOPO: 0x3, DIPO: 0x0

SPI_SIGNAL_MUX_SETTING_N 

SPI MUX combination N.

DOPO: 0x3, DIPO: 0x1

SPI_SIGNAL_MUX_SETTING_O 

SPI MUX combination O.

DOPO: 0x3, DIPO: 0x2

SPI_SIGNAL_MUX_SETTING_P 

SPI MUX combination P.

DOPO: 0x3, DIPO: 0x3

SPI transfer modes enum.

SPI transfer mode.

Enumerator
SPI_TRANSFER_MODE_0 

Mode 0.

Leading edge: rising, sample. Trailing edge: falling, setup

SPI_TRANSFER_MODE_1 

Mode 1.

Leading edge: rising, setup. Trailing edge: falling, sample

SPI_TRANSFER_MODE_2 

Mode 2.

Leading edge: falling, sample. Trailing edge: rising, setup

SPI_TRANSFER_MODE_3 

Mode 3.

Leading edge: falling, setup. Trailing edge: rising, sample

static void spi_attach_slave ( struct spi_slave_inst *const  slave,
const struct spi_slave_inst_config *const  config 
)
inlinestatic

Attaches an SPI peripheral slave.

This function will initialize the software SPI peripheral slave, based on the values of the config struct. The slave can then be selected and optionally addressed by the spi_select_slave function.

Parameters
[out]slavePointer to the software slave instance struct
[in]configPointer to the config struct

References spi_slave_inst::address, spi_slave_inst_config::address, spi_slave_inst::address_enabled, spi_slave_inst_config::address_enabled, Assert, port_config::direction, port_get_config_defaults(), PORT_PIN_DIR_OUTPUT, port_pin_set_config(), port_pin_set_output_level(), spi_slave_inst::ss_pin, and spi_slave_inst_config::ss_pin.

Referenced by trx_spi_init().

static void spi_disable ( struct spi_module *const  module)
inlinestatic

Disables the SERCOM SPI module.

This function will disable the SERCOM SPI module.

Parameters
[in,out]modulePointer to the software instance struct

References _sercom_get_interrupt_vector(), Assert, spi_is_syncing(), and system_interrupt_disable().

Referenced by spi_reset(), spi_set_baudrate(), and trx_spi_disable().

static void spi_enable ( struct spi_module *const  module)
inlinestatic

Enables the SERCOM SPI module.

This function will enable the SERCOM SPI module.

Parameters
[in,out]modulePointer to the software instance struct

References _sercom_get_interrupt_vector(), Assert, spi_is_syncing(), and system_interrupt_enable().

Referenced by spi_set_baudrate(), trx_spi_enable(), and trx_spi_init().

static void spi_get_config_defaults ( struct spi_config *const  config)
inlinestatic

Initializes an SPI configuration structure to default values.

This function will initialize a given SPI configuration structure to a set of known default values. This function should be called on any new instance of the configuration structures before being modified by the user application.

The default configuration is as follows:

  • Master mode enabled
  • MSB of the data is transmitted first
  • Transfer mode 0
  • MUX Setting D
  • Character size eight bits
  • Not enabled in sleep mode
  • Receiver enabled
  • Baudrate 100000
  • Default pinmux settings for all pads
  • GCLK generator 0
Parameters
[out]configConfiguration structure to initialize to default values

References Assert, spi_master_config::baudrate, spi_config::character_size, spi_config::data_order, GCLK_GENERATOR_0, spi_config::generator_source, spi_config::master, spi_config::mode, spi_config::mode_specific, spi_config::mux_setting, PINMUX_DEFAULT, spi_config::pinmux_pad0, spi_config::pinmux_pad1, spi_config::pinmux_pad2, spi_config::pinmux_pad3, spi_config::receiver_enable, spi_config::run_in_standby, SPI_CHARACTER_SIZE_8BIT, SPI_DATA_ORDER_MSB, SPI_MODE_MASTER, SPI_SIGNAL_MUX_SETTING_D, SPI_TRANSFER_MODE_0, and spi_config::transfer_mode.

Referenced by trx_spi_init().

enum status_code spi_init ( struct spi_module *const  module,
Sercom *const  hw,
const struct spi_config *const  config 
)

Initializes the SERCOM SPI module.

This function will initialize the SERCOM SPI module, based on the values of the config struct.

Parameters
[out]modulePointer to the software instance struct
[in]hwPointer to hardware instance
[in]configPointer to the config struct
Returns
Status of the initialization.
Return values
STATUS_OKModule initiated correctly
STATUS_ERR_DENIEDIf module is enabled
STATUS_BUSYIf module is busy resetting
STATUS_ERR_INVALID_ARGIf invalid argument(s) were provided

References _sercom_get_sercom_inst_index(), _sercom_instances, _sercom_set_handler(), _spi_check_config(), _spi_set_config(), Assert, spi_config::generator_source, spi_config::mode, sercom_set_gclk_generator(), system_gclk_chan_config::source_generator, SPI_MODE_MASTER, SPI_MODE_SLAVE, STATUS_BUSY, STATUS_ERR_DENIED, STATUS_ERR_INVALID_ARG, STATUS_OK, system_apb_clock_set_mask(), SYSTEM_CLOCK_APB_APBC, SYSTEM_CLOCK_APB_APBD, system_gclk_chan_enable(), system_gclk_chan_get_config_defaults(), and system_gclk_chan_set_config().

Referenced by trx_spi_init().

static bool spi_is_ready_to_read ( struct spi_module *const  module)
inlinestatic

Checks if the SPI module is ready to read data.

This function will check if the SPI module is ready to read data.

Parameters
[in]modulePointer to the software instance struct
Returns
Indication of whether the module is ready to read data or not.
Return values
trueIf the SPI module is ready to read data
falseIf the SPI module is not ready to read data

References Assert.

Referenced by spi_read(), spi_read_buffer_wait(), spi_select_slave(), spi_transceive_buffer_wait(), spi_transceive_wait(), spi_write_buffer_wait(), trx_aes_wrrd(), trx_frame_read(), trx_frame_write(), trx_reg_read(), trx_reg_write(), trx_sram_read(), and trx_sram_write().

static bool spi_is_ready_to_write ( struct spi_module *const  module)
inlinestatic

Checks if the SPI module is ready to write data.

This function will check if the SPI module is ready to write data.

Parameters
[in]modulePointer to the software instance struct
Returns
Indication of whether the module is ready to read data or not.
Return values
trueIf the SPI module is ready to write data
falseIf the SPI module is not ready to write data

References Assert.

Referenced by spi_read_buffer_wait(), spi_select_slave(), spi_transceive_buffer_wait(), spi_transceive_wait(), spi_write(), spi_write_buffer_wait(), trx_aes_wrrd(), trx_frame_read(), trx_frame_write(), trx_reg_read(), trx_reg_write(), trx_sram_read(), and trx_sram_write().

static bool spi_is_syncing ( struct spi_module *const  module)
inlinestatic

Determines if the SPI module is currently synchronizing to the bus.

This function will check if the underlying hardware peripheral module is currently synchronizing across multiple clock domains to the hardware bus. This function can be used to delay further operations on the module until it is ready.

Parameters
[in]moduleSPI hardware module
Returns
Synchronization status of the underlying hardware module.
Return values
trueModule synchronization is ongoing
falseModule synchronization is not ongoing

References Assert.

Referenced by spi_disable(), spi_enable(), spi_reset(), and spi_set_baudrate().

static bool spi_is_write_complete ( struct spi_module *const  module)
inlinestatic

Checks if the SPI in master mode has shifted out last data, or if the master has ended the transfer in slave mode.

This function will check if the SPI master module has shifted out last data, or if the slave select pin has been drawn high by the master for the SPI slave module.

Parameters
[in]modulePointer to the software instance struct
Returns
Indication of whether any writes are ongoing.
Return values
trueIf the SPI master module has shifted out data, or slave select has been drawn high for SPI slave
falseIf the SPI master module has not shifted out data

References Assert.

Referenced by spi_read_buffer_wait(), spi_transceive_buffer_wait(), spi_write_buffer_wait(), trx_aes_wrrd(), trx_frame_read(), trx_frame_write(), trx_reg_read(), trx_reg_write(), trx_sram_read(), and trx_sram_write().

static enum status_code spi_lock ( struct spi_module *const  module)
inlinestatic

Attempt to get lock on driver instance.

This function checks the instance's lock, which indicates whether or not it is currently in use, and sets the lock if it was not already set.

The purpose of this is to enable exclusive access to driver instances, so that, e.g., transactions by different services will not interfere with each other.

Parameters
[in,out]modulePointer to the driver instance to lock
Return values
STATUS_OKIf the module was locked
STATUS_BUSYIf the module was already locked

References STATUS_BUSY, STATUS_OK, system_interrupt_enter_critical_section(), and system_interrupt_leave_critical_section().

static enum status_code spi_read ( struct spi_module *const  module,
uint16_t *  rx_data 
)
inlinestatic

Reads last received SPI character.

This function will return the last SPI character shifted into the receive register by the spi_write function.

Note
The spi_is_ready_to_read function should be called before calling this function.
Receiver must be enabled in the configuration.
Parameters
[in]modulePointer to the software instance struct
[out]rx_dataPointer to store the received data
Returns
Status of the read operation.
Return values
STATUS_OKIf data was read
STATUS_ERR_IOIf no data is available
STATUS_ERR_OVERFLOWIf the data is overflown

References Assert, SPI_CHARACTER_SIZE_9BIT, spi_is_ready_to_read(), STATUS_ERR_IO, STATUS_ERR_OVERFLOW, and STATUS_OK.

Referenced by spi_read_buffer_wait(), spi_select_slave(), spi_transceive_buffer_wait(), spi_transceive_wait(), spi_write_buffer_wait(), trx_aes_wrrd(), trx_frame_read(), trx_frame_write(), trx_reg_read(), trx_reg_write(), trx_sram_read(), and trx_sram_write().

enum status_code spi_read_buffer_wait ( struct spi_module *const  module,
uint8_t *  rx_data,
uint16_t  length,
uint16_t  dummy 
)

Reads buffer of length SPI characters.

This function will read a buffer of data from an SPI peripheral by sending dummy SPI character if in master mode, or by waiting for data in slave mode.

Note
If address matching is enabled for the slave, the first character received and placed in the buffer will be the address.
Parameters
[in]modulePointer to the software instance struct
[out]rx_dataData buffer for received data
[in]lengthLength of data to receive
[in]dummy8- or 9-bit dummy byte to shift out in master mode
Returns
Status of the read operation.
Return values
STATUS_OKIf the read was completed
STATUS_ABORTEDIf transaction was ended by master before the entire buffer was transferred
STATUS_ERR_INVALID_ARGIf invalid argument(s) were provided
STATUS_ERR_TIMEOUTIf the operation was not completed within the timeout in slave mode
STATUS_ERR_DENIEDIf the receiver is not enabled
STATUS_ERR_OVERFLOWIf the data is overflown

References Assert, SPI_CHARACTER_SIZE_9BIT, spi_is_ready_to_read(), spi_is_ready_to_write(), spi_is_write_complete(), SPI_MODE_MASTER, SPI_MODE_SLAVE, spi_read(), SPI_TIMEOUT, spi_write(), STATUS_ABORTED, STATUS_BUSY, STATUS_ERR_DENIED, STATUS_ERR_INVALID_ARG, STATUS_ERR_TIMEOUT, and STATUS_OK.

void spi_reset ( struct spi_module *const  module)

Resets the SPI module.

This function will reset the SPI module to its power on default values and disable it.

Parameters
[in,out]modulePointer to the software instance struct

References Assert, spi_disable(), and spi_is_syncing().

enum status_code spi_select_slave ( struct spi_module *const  module,
struct spi_slave_inst *const  slave,
const bool  select 
)

Selects slave device.

This function will drive the slave select pin of the selected device low or high depending on the select Boolean. If slave address recognition is enabled, the address will be sent to the slave when selecting it.

Parameters
[in]modulePointer to the software module struct
[in]slavePointer to the attached slave
[in]selectBoolean stating if the slave should be selected or deselected
Returns
Status of the operation.
Return values
STATUS_OKIf the slave device was selected
STATUS_ERR_UNSUPPORTED_DEVIf the SPI module is operating in slave mode
STATUS_BUSYIf the SPI module is not ready to write the slave address

References spi_slave_inst::address, spi_slave_inst::address_enabled, Assert, port_pin_set_output_level(), spi_is_ready_to_read(), spi_is_ready_to_write(), SPI_MODE_MASTER, spi_read(), spi_write(), spi_slave_inst::ss_pin, STATUS_BUSY, STATUS_ERR_UNSUPPORTED_DEV, and STATUS_OK.

Referenced by trx_aes_wrrd(), trx_frame_read(), trx_frame_write(), trx_reg_read(), trx_reg_write(), trx_sram_read(), and trx_sram_write().

enum status_code spi_set_baudrate ( struct spi_module *const  module,
uint32_t  baudrate 
)

Set the baudrate of the SPI module.

This function will set the baudrate of the SPI module.

Parameters
[in]modulePointer to the software instance struct
[in]baudrateThe baudrate wanted
Returns
The status of the configuration.
Return values
STATUS_ERR_INVALID_ARGIf invalid argument(s) were provided
STATUS_OKIf the configuration was written

References _sercom_get_sercom_inst_index(), _sercom_get_sync_baud_val(), Assert, spi_disable(), spi_enable(), spi_is_syncing(), STATUS_ERR_INVALID_ARG, STATUS_OK, and system_gclk_chan_get_hz().

static void spi_slave_inst_get_config_defaults ( struct spi_slave_inst_config *const  config)
inlinestatic

Initializes an SPI peripheral slave device configuration structure to default values.

This function will initialize a given SPI slave device configuration structure to a set of known default values. This function should be called on any new instance of the configuration structures before being modified by the user application.

The default configuration is as follows:

  • Slave Select on GPIO pin 10
  • Addressing not enabled
Parameters
[out]configConfiguration structure to initialize to default values

References spi_slave_inst_config::address, spi_slave_inst_config::address_enabled, Assert, and spi_slave_inst_config::ss_pin.

Referenced by trx_spi_init().

enum status_code spi_transceive_buffer_wait ( struct spi_module *const  module,
uint8_t *  tx_data,
uint8_t *  rx_data,
uint16_t  length 
)

Sends and receives a buffer of length SPI characters.

This function will send and receive a buffer of data via the SPI.

In master mode the SPI characters will be sent immediately and the received SPI character will be read as soon as the shifting of the SPI character is complete.

In slave mode this function will place the data to be sent into the transmit buffer. It will then block until an SPI master has shifted the complete buffer and the received data is available.

Parameters
[in]modulePointer to the software instance struct
[in]tx_dataPointer to the buffer to transmit
[out]rx_dataPointer to the buffer where received data will be stored
[in]lengthNumber of SPI characters to transfer
Returns
Status of the operation.
Return values
STATUS_OKIf the operation was completed
STATUS_ERR_INVALID_ARGIf invalid argument(s) were provided
STATUS_ERR_TIMEOUTIf the operation was not completed within the timeout in slave mode
STATUS_ERR_DENIEDIf the receiver is not enabled
STATUS_ERR_OVERFLOWIf the data is overflown

References Assert, SPI_CHARACTER_SIZE_9BIT, spi_is_ready_to_read(), spi_is_ready_to_write(), spi_is_write_complete(), SPI_MODE_MASTER, SPI_MODE_SLAVE, spi_read(), SPI_TIMEOUT, spi_write(), STATUS_ABORTED, STATUS_BUSY, STATUS_ERR_DENIED, STATUS_ERR_INVALID_ARG, STATUS_ERR_TIMEOUT, and STATUS_OK.

enum status_code spi_transceive_wait ( struct spi_module *const  module,
uint16_t  tx_data,
uint16_t *  rx_data 
)

Sends and reads a single SPI character.

This function will transfer a single SPI character via SPI and return the SPI character that is shifted into the shift register.

In master mode the SPI character will be sent immediately and the received SPI character will be read as soon as the shifting of the data is complete.

In slave mode this function will place the data to be sent into the transmit buffer. It will then block until an SPI master has shifted a complete SPI character, and the received data is available.

Note
The data to be sent might not be sent before the next transfer, as loading of the shift register is dependent on SCK.
If address matching is enabled for the slave, the first character received and placed in the buffer will be the address.
Parameters
[in]modulePointer to the software instance struct
[in]tx_dataSPI character to transmit
[out]rx_dataPointer to store the received SPI character
Returns
Status of the operation.
Return values
STATUS_OKIf the operation was completed
STATUS_ERR_TIMEOUTIf the operation was not completed within the timeout in slave mode
STATUS_ERR_DENIEDIf the receiver is not enabled
STATUS_ERR_OVERFLOWIf the incoming data is overflown

References Assert, spi_is_ready_to_read(), spi_is_ready_to_write(), SPI_MODE_SLAVE, spi_read(), SPI_TIMEOUT, spi_write(), STATUS_BUSY, STATUS_ERR_DENIED, STATUS_ERR_TIMEOUT, and STATUS_OK.

static void spi_unlock ( struct spi_module *const  module)
inlinestatic

Unlock driver instance.

This function clears the instance lock, indicating that it is available for use.

Parameters
[in,out]modulePointer to the driver instance to lock
Return values
STATUS_OKIf the module was locked
STATUS_BUSYIf the module was already locked
static enum status_code spi_write ( struct spi_module module,
uint16_t  tx_data 
)
inlinestatic

Transfers a single SPI character.

This function will send a single SPI character via SPI and ignore any data shifted in by the connected device. To both send and receive data, use the spi_transceive_wait function or use the spi_read function after writing a character. The spi_is_ready_to_write function should be called before calling this function.

Note that this function does not handle the SS (Slave Select) pin(s) in master mode; this must be handled from the user application.

Note
In slave mode, the data will not be transferred before a master initiates a transaction.
Parameters
[in]modulePointer to the software instance struct
[in]tx_dataData to transmit
Returns
Status of the procedure.
Return values
STATUS_OKIf the data was written
STATUS_BUSYIf the last write was not completed

References Assert, spi_is_ready_to_write(), STATUS_BUSY, and STATUS_OK.

Referenced by spi_read_buffer_wait(), spi_select_slave(), spi_transceive_buffer_wait(), spi_transceive_wait(), spi_write_buffer_wait(), trx_aes_wrrd(), trx_frame_read(), trx_frame_write(), trx_reg_read(), trx_reg_write(), trx_sram_read(), and trx_sram_write().

enum status_code spi_write_buffer_wait ( struct spi_module *const  module,
const uint8_t *  tx_data,
uint16_t  length 
)

Sends a buffer of length SPI characters.

This function will send a buffer of SPI characters via the SPI and discard any data that is received. To both send and receive a buffer of data, use the spi_transceive_buffer_wait function.

Note that this function does not handle the _SS (slave select) pin(s) in master mode; this must be handled by the user application.

Parameters
[in]modulePointer to the software instance struct
[in]tx_dataPointer to the buffer to transmit
[in]lengthNumber of SPI characters to transfer
Returns
Status of the write operation.
Return values
STATUS_OKIf the write was completed
STATUS_ABORTEDIf transaction was ended by master before entire buffer was transferred
STATUS_ERR_INVALID_ARGIf invalid argument(s) were provided
STATUS_ERR_TIMEOUTIf the operation was not completed within the timeout in slave mode

References Assert, SPI_CHARACTER_SIZE_9BIT, spi_is_ready_to_read(), spi_is_ready_to_write(), spi_is_write_complete(), SPI_MODE_MASTER, SPI_MODE_SLAVE, spi_read(), SPI_TIMEOUT, spi_write(), STATUS_ABORTED, STATUS_BUSY, STATUS_ERR_INVALID_ARG, STATUS_ERR_TIMEOUT, and STATUS_OK.