Open matt-wood-ct opened 4 months ago
Related with #66664
Hi @matt-wood-ct,
The short answer is that the ws2812_spi
driver relies on the fact that the MOSI signal is idle low.
Unfortunately, adding a start/stop frame is not a great strategy. See #66664 where it has already been discussed. Note that some WS2812-compatible controllers such as the Everlight B1414 have a 250us reset delay. At a 6MHz frequency, this would waste 188 bytes of memory...
Si in order to use the ws2812_spi driver you need to configure your SPI controller to get the MOSI low when idle.
And if it is not possible then the ws2812_i2s
, ws2812_gpio
, and (hopefully soon) ws2812_uart
drivers are good alternatives.
Thanks @simonguinot for the quick response, I'll take a look at the NXP reference manual and zephyr SPI driver and see if I can adjust the SPI to behave in that manner, I see a few NXP forum threads wanting similar things with mixed results so it may be possible 😄.
Side note, perhaps if this a somewhat common issue as MOSI is not necessarily defined when the bus is idle, would it be worth having some kind of mitigation in the driver toggleable on a 'as needed' basis e.g. kconfig default'd false. It seems that we all agree manually inserting start/stop frames does in fact work, I agree with your comments about RAM waste, but there are more optimal ways to implement the same behaviour without growing the buffer.
For the moment I have drafted a pull request just to float the idea of a default disabled preamble system which would allow users in a position where the bus behaviour is problem to apply a simple device level tree fix. How do people feel about this?
This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.
FYI I am going to resume working on this and the associated PR
Describe the bug
When driving a strip of WS2812B LEDs from the IMXRT1040 SOC using the
WS2812_SPI
driver the first LED is not controlledTo Reproduce Setup a board based on an IMXRT series process with an overlay which configures the
ws2812-spi
driver, example configuration:Run the LED strip driver sample.
See LEDs sequencing through colours except the first LED remains off.
Expected behavior All LEDs including the first LED should go through the intended colour sequence.
Impact In tree patch created, can bring the driver out of tree until fix is implemented/adopted
Logs and console output N/A
Environment (please complete the following information):
Additional context
I have investigated the problem and create a patch which can resolve the problem in my case, but I am unclear why a similar feature is not already in tree, unless I am missing something... which I probably am 😄
What I found was that the SPI MOSI had LED data shifted out as expected but at the start of the burst the transition was not graceful so the LEDs appear to ignore the first LED worth of data. Below is a logic analyser capture of the line activity:
The fix I discovered was to add some bus low time at the start (80uS) to trigger a reset on the LED. After this reset the burst of data can be sent and all LEDs behave well. I achived this by adding a head an tail of zeros onto the SPI data which is sent on
ws2812_strip_update_rgb
, in my case 64 byte of zero which translated to around 85uS of low on paper and ~82uS in practice on my hardware. This yields a bus behaviour which looks like this:Patch: WS2812.patch This patch is not tidy enough to merge but it is functional, I imagine any production ready implementation would expose the head and tail delay parameters as device tree parameters for per SOC tweaking similar to the
spi-one-frame
andspi-zero-frame
values.One thing I did not understand when reading through the driver was this line https://github.com/zephyrproject-rtos/zephyr/blob/596ef0a519eec584e2c403927543b130a7166a45/drivers/led_strip/ws2812_spi.c#L132 It says reset delay, but the bus is not being driven at this time so they delay does not actually cause the intended 50uS of bus low time the datasheet calls for: The end effect of that line is the driver just waits 50uS while doing nothing with the bus, in most cases the bus will be driving the MOSI line high during this time nullifying any useful effect.