spi-bcm2711 driver example
This example uses the implementation of the RPi4 SPI driver spi-bcm2711, available in the RPi4 BSP download package, com.qnx.qnx800.bsp.hw.raspberrypi_bcm2711_rpi4, under src/hardware/spi/bcm2711.
Driver implementation
The driver implements the required functions described below and static-links against the libio-spi library. The library provides the main executable entry point, which calls spi_init() to connect to implementation and initialize the driver; it also starts the resource manager to handle the client communication.
The following table maps the spi-bcm2711 driver implementations to their related documentation:
| Related section | Implementation source file | Implementation name |
|---|---|---|
| Define a structure | bcm2711spi.h | bcm2711_api_t |
| Clean up the driver | fini.c | bcm2711spi_fini() |
| Set up a config driver | setcfg.c | bcm2711spi_setcfg() |
| Exchange data | xfer.c | bcm2711spi_xfer() |
| Initialize the driver | init.c | init_device() spi_init() |
void bcm2711spi_drvinfo(const void *const hdl, spi_drvinfo_t *info)- Implements the drvinfo() function in the spi_funcs_t structure.
- Gets the SPI driver information.
- Arguments:
- hdl — The handle of the low-level module returned by spi_init().
- info — A pointer to store the SPI driver information.
void void bcm2711spi_devinfo(const void *const hdl, const spi_dev_t *const spi_dev, spi_devinfo_t *const info)-
- Implements the devinfo() function in the spi_funcs_t structure.
- Obtains the SPI device information.
- Arguments:
- hdl — The handle of the low-level module returned by spi_init().
- spi_dev — A pointer to the SPI device structure.
- info — A pointer to store the SPI driver information.
int bcm2711spi_dmaxfer(void *const hdl, spi_dev_t *spi_dev, dma_addr_t *addr, const uint32_t tnbytes, const uint32_t rnbytes)-
- Implements the dma_xfer() function in the spi_funcs_t structure.
- Initiates a DMA transaction.
- Arguments:
- hdl — The handle of the low-level module returned by spi_init().
- spi_dev — A pointer to the SPI device structure.
- addr — A pointer to the DMA address structure.
- tnbytes — The number of transmit bytes.
- rnbytes — The number of receive bytes.
- Returns:
- EOK — Success.
- errno — An error occurred.
int bcm2711_dma_allocbuf(void *const hdl, dma_addr_t *addr, const uint32_t len)-
- Implements the dma_allocbuf() function in the spi_funcs_t structure.
- Allocates a DMA buffer.
- Arguments:
- hdl — The handle of the low-level module returned by spi_init().
- addr — A pointer to the DMA address structure.
- len — The length, in bytes, of the data for this DMA transaction.
- Returns:
- EOK — Success.
- errno — An error occurred.
int bcm2711_dma_freebuf(void *const hdl, dma_addr_t *addr)-
- Implements the dma_freebuf() function in the spi_funcs_t structure.
- Frees a DMA buffer.
- Arguments:
- hdl — The handle of the low-level module returned by spi_init().
- addr — A pointer to the DMA address structure.
- Returns:
- EOK — Success.
- errno — An error occurred.
Client samples
- Generic SPI client API, implemented as static library (rpi_spi) — Provides the underlying logic to communicate with the SPI driver.
- WS 281x LED static library (librpi_ws281x) — Provides a generic API to write colors to a collection of WS 281x LEDs. This sample is suitable for simpler control of one or more LED strips, or one or more LED matrices, but doesn't contain specialized logic for managing matrices in a transparent fashion. It's a smaller port of the Linux library of the same name (https://github.com/jgarff/rpi_ws281x), but focuses only on the SPI driver of the original library. The implementation of this sample's SPI logic is based on the rpi_spi sample above.
- LED Strip Matrix application (rpi-ws281x-rainbow) — A sample application that demonstrates how to use the librpi_ws281x APIs to display a rainbow.
The hardware configuration for WS281x is:
-
Mode:
0b00010000010000100000 -
Frequency:
6500000
rpi_spi_configure_device(bus_number, device_number, 0b00010000010000100000, 6500000)
rpi_spi_write_read_data(bus_number, device_number, data, data_size)For the full initialization implementation for WS281x, refer to the ws2811_render() and spi_transfer() functions in rpi_ws281x.c: https://gitlab.com/qnx/projects/hardware-component-samples/-/blob/main/common/rpi_ws281x/rpi_ws281x.c.
