At least on nRF52 devices, we are taking too much time between pixels
dealing with overhead inside the SPI driver transceive calls. This is
leading to dropped frames, because the dead time between frames is
long enough (5000ns+) to look like a reset pulse to the LED strip.
Given this SPI driver limitation, it seems this LED driver's design
decision to rely on SPI peripherals as efficient pulse generators
doesn't work well in practice.
The right way to handle this is probably to switch from SPI to
efficient inline assembly which bit-bangs the pulses with interrupts
disabled.
This is what other efficient libraries do to drive this type of
LED (e.g. FastLED uses C++ templates that expand into such
assembly). The Zephyr GPIO API doesn't support doing that in a
portable fashion, unfortunately.
For now, we'll cheat by pre-allocating enough buffer space to send the
entire strip's worth of data.
This is preposterously inefficient (8x memory overhead since there's
one byte to make a SPI frame for each bit of color), but makes the
driver work correctly.
(Note that using timer peripherals as pulse generators, when combined
with DMA for efficiency, would also lead to similar levels of
overhead.)
Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
The return of memset is never checked. This patch explicitly ignore
the return to avoid MISRA-C violations.
The only directory excluded directory was ext/* since it contains
only imported code.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
tx_bufs/tx_count and rx_bufs/rx_count can be hold in another dedicated
structure, thus reducing the number of parameters to transceive. This
permits to avoid using the stack when calling transceive.
Since we saved parameters, we can expose back the struct device pointer,
to stay consistent with other device driver APIs.
Fixes#5839
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
The WS2812 LED driver IC has a one-wire interface which encodes bit
values as pulse widths.
The ICs themselves are basically shift registers. Roughly speaking, a
"short" pulse shifts in a zero bit, a "long" pulse shifts in a one
bit, and an inter-pulse gap exceeding a reset time threshold causes a
pixel to latch the shifted-in color values. Each chip has an output
pin for daisy chaining. Refer to the chip datsheets and comments in
Kconfig.ws2812 for more details.
To meet timing without hogging the core, this driver generates pulses
using SPI. To work, this requires the MOSI line to stay low between
SPI frames, and for inter-frame delays to be less than the reset pulse
time.
There are other ways do it (PWM + DMA on some SoCs, GPIO bit-banging
if no other tasks need the core), but this is a reasonably
general-purpose implementation.
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>