Name
Porting — Adding SPI support to new hardware
Description
Adding SPI support to an eCos port can take two forms. If there is
already an SPI bus driver for the target hardware then both that
driver and this generic SPI package CYGPKG_IO_SPI
should be included in the ecos.db target entry.
Typically the platform HAL will need to supply some platform-specific
information needed by the bus driver. In addition the platform HAL
should provide cyg_spi_device structures for
every device attached to the bus. The exact details of this depend on
the bus driver so its documentation should be consulted for further
details. If there is no suitable SPI bus driver yet then a new driver
package will have to be written.
Adding a Device
The generic SPI package CYGPKG_IO_SPI
defines a
data structure cyg_spi_device. This contains
the information needed by the generic package, but not the additional
information needed by a bus driver to interact with the device. Each
bus driver will define a larger data structure, for example
cyg_mcf52xx_qspi_device, which contains a
cyg_spi_device as its first field. This is
analogous to C++ base and derived classes, but without any use of
virtual functions. The bus driver package should be consulted for the
details.
During initialization an SPI bus driver may need to know about all the devices attached to that bus. For example it may need to know which cpu pins should be configured as chip selects rather than GPIO pins. To achieve this all device definitions should specify the particular bus to which they are attached, for example:
struct cyg_mcf52xx_qspi_device hal_spi_atod CYG_SPI_DEVICE_ON_BUS(0) = { .spi_common.spi_bus = &cyg_mcf52xx_qspi_bus, … };
The CYG_SPI_DEVICE_ON_BUS
macro adds information
to the structure which causes the linker to group all such structures
in a single table. The bus driver's initialization code can then
iterate over this table.
Adding Bus Support
An SPI bus driver usually involves a new hardware package. This needs to perform the following:
- Define a device structure which contains a cyg_spi_device as its first element. This should contain all the information needed by the bus driver to interact with a device on that bus.
Provide functions for the following operations:
spi_transaction_begin
spi_transaction_transfer
spi_transaction_tick
spi_transaction_end
spi_get_config
spi_set_config
These correspond to the main API functions, but can assume that the bus is already locked so no other thread will be manipulating the bus or any of the attached devices. Some of these operations may be no-ops.
- Define a bus structure which contains a cyg_spi_bus as its first element. This should contain any additional information needed by the bus driver.
- Optionally, instantiate the bus structure. The instance should have a well-known name since it needs to be referenced by the device structure initializers. For some drivers it may be best to create the bus inside the driver package. For other drivers it may be better to leave this to the platform HAL or the application. It depends on how much platform-specific knowledge is needed to fill in the bus structure.
- Create a HAL table for the devices attached to this bus.
-
Arrange for the bus to be initialized early on during system
initialization. Typically this will happen via a prioritized static
constructor with priority
CYG_INIT_BUS_SPI
. As part of this initialization the bus driver should invoke theCYG_SPI_BUS_COMMON_INIT
macro on its cyg_spi_bus field. - Provide the appropriate documentation, including details of how the SPI device structures should be initialized.
There are no standard SPI testcases. It is not possible to write SPI code without knowing about the devices attached to the bus, and those are inherently hardware-specific.
2024-03-18 | Open Publication License |