CYGPKG_DEVS_SPI_ATMEL_USPI — eCos Support for the Microchip (Atmel) USART-as-SPI Bus


The Microchip (previously Atmel) SAM E70, S70, V70 and V71 processors do come with on-chip SPI controllers, but also with the ability to configure the on-chip USART controllers as SPI masters. This package provides an eCos bus driver for those USART-as-SPI interfaces. The CYGPKG_DEVS_SPI_ARM_AT91 package provides the bus driver support for the standard SPI controllers.

This package implements the functionality defined by the generic SPI package CYGPKG_IO_SPI. The driver supports both polled and DMA-driven transfers. Typical supported transfer rates range from 3KHz to 25MHz, although the exact details depend on the specific processor configuration.

This bus driver package does not instantiate any cyg_spi_device structures. Exactly which devices are attached to the SPI bus is a characteristic of the platform so usually it is the platform HAL which provides the device instances.

Configuration Options

This SPI bus driver package should be loaded automatically when selecting a target containing a suitable SAM processor with USART-as-SPI hardware, and it should never be necessary to load the package explicitly. If the application does not use any of the SPI functionality then all the SPI support code will be removed at link-time and the application does not suffer any overheads.

The package contains a single configuration option CYGNUM_DEVS_SPI_ATMEL_USPI_BAUD_RATE_MAX. Usually this option will not need to be manipulated by application developers, since it purely sets an upper bound on the acceptable device baudrate that will be accepted, though may not be achievable depending on the CPU configuration.

The only other configuration options provided by this package relate to compiler flags.

Instantiating Buses

In the platform CDL, when this CYGPKG_DEVS_SPI_ATMEL_USPI is configured, an implements entry should be provided for the USART-as-SPI bus to instantiate.


Currently the CYGPKG_HAL_CORTEXM_SAM HAL allows for the dedicated SPI buses numbered 0 and 1, and the USART-as-SPI buses numbered 2..4.

For example, the samx70_ek platform CDL provides for SPI bus#2 by declaring:


When a bus is implemented the Chip-Select GPIOs associated with the bus (at least one) should be provided by the platform CDL defining a corresponding CYGHWR_HAL_CORTEXM_SAM_SPIx_CS_GPIOS definition for the bus in question.

For the SPI bus#2 example above the platform CDL would also define CYGHWR_HAL_CORTEXM_SAM_SPI2_CS_GPIOS option and provide the list of chip-select pins, e.g.:

default_value { "SPI_CS(B,3)" }

Defining Devices

For most boards the platform HAL will create cyg_spi_device instances for all attached SPI devices, and will initialize the system so that the SPI-related processor pins are connected appropriately.

Device instances should take the form of a cyg_spi_atmel_device_t structure, which contains a cyg_spi_device as its first field. For example, for a device on bus#2:

#include <cyg/io/spi_atmel_uspi.h>
cyg_spi_atmel_device_t hal_spi_example CYG_SPI_DEVICE_ON_BUS(2) = {
    .spi_device.spi_bus = &cyg_spi_atmel_uspi_bus2,

This defines a variable hal_spi_example which can be used by other packages or by application code as an argument to the I/O functions provided by the generic SPI package CYGPKG_IO_SPI. A gcc extension, designated initializers, is used to fill in the spi_device.spi_bus structure field. The structure contains a further seven fields which define exactly how to interact with the specific SPI device.

This is the index into the CYGHWR_HAL_CORTEXM_SAM_SPIx_CS_GPIOS list of GPIOs for the specific Chip-Select GPIO used to select access to the device on the relevant SPI bus.
The clock polarity (0 or 1).
The clock phase (0 or 1).
The SCK baudrate used when communicating with the device.
Required microsecond delay between CS active and the transfer starting.
Required microsecond delay between transfer ending and CS going inactive.
Minimum microsecond delay between two transfers (between CS inactive to active again).

For example, the following instantaties a AT25080 serial EEPROM memory device on SPI bus#2:

#include <cyg/io/spi_atmel_uspi.h>
cyg_spi_atmel_device_t cyg_aardvark_at25080 CYG_SPI_DEVICE_ON_BUS(2) = {
    .spi_device.spi_bus = &cyg_spi_atmel_uspi_bus2,
    .dev_num     = 0,       // CS#0
    .cl_pol      = 0,       // Clock polarity
    .cl_pha      = 1,       // Clock phase
    .cl_brate    = 2000000, // Clock baud rate 2MHz. At 3.3v 2.1MHz is allowed for this part.
    .cs_up_udly  = 1,       // Tcss (CS setup time) for this part at 3.3V is 250ns.
    .cs_dw_udly  = 1,       // Tcsh (CS hold time) for this part at 3.3V is 250ns.
    .tr_bt_udly  = 1        // Tcs (CS high time) for this part at 3.3V is 250ns.