SPI Protocol Background
https://en.wikipedia.org/wiki/Serial_Peripheral_Interface
Adafruit WS2812 LED matrix
https://www.adafruit.com/product/1487
The NXP MCXA153 Reference Manual
The NXP MCXA153-FRDM Board
MCXA153 WS2812 Example Code
The Serial Peripheral Interface (SPI) is ubiquitous in embedded systems for interfacing to external peripherals such flash memories, EEPROMs, analog to digital converters and sensors. SPI is a synchronous serial data transmission standard which has a data path from a controller to a peripheral and vice-versa. Data bits are sent synchronous to a clock and there is typically a “chip select” signal to flag an active transaction with a downstream peripheral.
1-byte SPI Transfer in 0,0 Mode. Data Is sampled on the rising edge and shifted on falling edge
Most peripherals expect some sort of multi-byte transaction where data from the controller has an address and/or command structure. At the core of typical SPI controller is a shift register. The shift register is often surrounded by logic to control clock phase, the chip select signaling and input data loading.
The LPSPI Peripheral in the NXP MCX A Series Microcontrollers
Once you understand that SPI is implemented with a shift register with control logic, you can envision using it for applications outside of the typical use cases. Consider the scenario where the bytes 0xFF and 0xAA are transmitted with a chip select.
This example is shown with a gap between data bytes. This is not uncommon for simple MCU software SPI implementations that might poll for when data can be written to the shift register. The MCXA153 has FIFOs in front of the core shift register. This enables the MCU to keep the shift register loaded with data to generate a continuous stream.
In this example, we assumed 8-bit transactions. The SPI controller in the MCXA153 can shift up to 32-bits at a time. Next, let’s remove the chip select and clock signal and then consider the data signal as long series of data bits.
Precise control of a data stream with a fixed time quanta
If the SPI output shift register is kept loaded with new data as the prior data is being shifted out, we can synthesis arbitrary data patterns with a precise time quanta. The SPI peripheral still has a clock, we are choosing not to expose it. The time quanta δt is set by the internal clocking to the SPI peripheral.
Synthesizing a continuous waveform pattern is achieved by using Direct Memory Access (DMA). The MCXA153 has a DMA controller which can automate transfers of large blocks of data to the SPI peripheral to ensure a 100% continuous data stream
The MCX A Series eDMA Controller
The desired waveform is precomputed, then DMA is used to transfer large blocks of the precomputed data to the SPI peripheral for a continuous data stream. DMA transactions can be linked using a “ping-pong” buffer scheme. The MCU can pre-compute the next data buffer while the DMA controller is moving the current buffer.
An example of this technique is to efficiently drive WS2812 “intelligent” LEDs with little CPU overhead. These LEDs are designed to be “daisy chained” together with control via a signal bit data stream. You can find them used in very long LED strips and matrix arrays.
The Adafruit 8x8 LED Matrix array using the WS2812.
The WS2812 command protocol uses a single wire data scheme where data bit symbols are encoded via a pulse width.
The WS2812 data bit symbols encoded in time
The data stream for RGB color data is a long series of these symbols that is propagated down the LED daisy chain. One method to generate this bit stream is to a combination of SPI and DMA. We can adjust the clock rate of the SPI controller such that one data byte spans 2.5uS. Then, we use two different data bytes to represent the “1” and the “0” symbols. Each “byte” of data in the RGB color stream can be encoded as eight bytes in a SPI transaction.
A long chain of RGB data can then be precomputed into a larger buffer.
Once the data buffer is computed, it can be transferred using the DMA controller.
The primary advantage with this approach is that very little CPU time is needed to move the data stream. The combination of the DMA controller and SPI controller efficiently shift data in the background. Sample code for that uses the NXP FRDM-MCXA153 here:
https://github.com/wavenumber-eng/mcxa153_spi_neopixel.git
The DMA controller in the low cost MCXA153 enables some very interesting IO uses cases. In this example we used the SPI controller, however we could have also combined the DMA with a PWM to achieve the same result. SPI is ubiquitous in many MCUs and is a easy to way to synthesize data patterns.
In a future paper, we will look at using SPI slave with DMA to generate a Pulse Density Modulation(PDM) pattern . The goal being to emulate a PDM digital microphone for audio system testing. I hope these examples enable you to consider ways to use a SPI controller with DMA for new and interesting use cases.
SPI Protocol Background
https://en.wikipedia.org/wiki/Serial_Peripheral_Interface
Adafruit WS2812 LED matrix
https://www.adafruit.com/product/1487
The NXP MCXA153 Reference Manual
The NXP MCXA153-FRDM Board
MCXA153 WS2812 Example Code