-
Notifications
You must be signed in to change notification settings - Fork 7.7k
drivers: led_strip: ws2812_i2s: add full pre reset if active low #89203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
drivers: led_strip: ws2812_i2s: add full pre reset if active low #89203
Conversation
Idle is high if output is active low. Hold idle inactive for full reset duration before sending strip data to ensure initial data is not corrupted. Signed-off-by: Jeppe Odgaard <jeppe.odgaard@prevas.dk>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @jeppenodgaard,
IIUC the problem is that the I2S signal is active at idle state on your device, isn't it ? And then the signal edge when starting the data transmission is interpreted by the first LED controller of the strip as a bit ? Is that correct ?
Note that we had a lot of similar issues on the ws2812_spi
driver with several SPI controllers / SoC. Most of them have been fixed at the SPI controller / SoC level.
And I'd like to have the same resolution here too.
@@ -83,7 +85,7 @@ static int ws2812_strip_update_rgb(const struct device *dev, struct led_rgb *pix | |||
tx_buf = (uint32_t *)mem_block; | |||
|
|||
/* Add a pre-data reset, so the first pixel isn't skipped by the strip. */ | |||
for (uint16_t i = 0; i < WS2812_I2S_PRE_DELAY_WORDS; i++) { | |||
for (uint16_t i = 0; i < pre_delay_words; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if the signal is active low, we are waiting for a reset delay before AND after sending data ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Otherwise the first LED is misbehaving.
@@ -69,6 +69,8 @@ static int ws2812_strip_update_rgb(const struct device *dev, struct led_rgb *pix | |||
const uint8_t sym_one = cfg->nibble_one; | |||
const uint8_t sym_zero = cfg->nibble_zero; | |||
const uint32_t reset_word = cfg->active_low ? ~0 : 0; | |||
const uint16_t pre_delay_words = | |||
cfg->active_low ? cfg->reset_words : WS2812_I2S_PRE_DELAY_WORDS_DEFAULT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that having a signal active at idle state can also happen with a signal active high.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True. It should probably have its own property (unless it can be resolved at a lower level as you suggest).
Hi @simonguinot
Yes. It is the samme issue with the SPI driver.
Yes.
Since How was it resolved at SPI/SoC level? |
@simonguinot I am not sure how to fix this at at a lower level. |
Yes it is pretty much the same kind of issue. The MOSI state when idle was OK, but became high when the SPI controller was preparing to transmit. I also can find:
I know there are other cases, but I can't find them. Some have also been discussed on Discord. What SoC are you using ? Did you check if the pin can be configured to invert the polarity for example ? |
Thank you for the links @simonguinot! Those were exactly what I was looking for. I read through the comments in #66664 and they make a lot of sense.
A am using an STM32H563.
I check the reference manual and I see no way to control the MOSI polarity and idle state. I am not sure it makes sense to control MOSI idle level when using SPI for ordinary SPI communication because it is unused when CLK is inactive nor can I see anything specified in the "official SPI specification". Therefore I do not think controlling the idle MOSI level makes sense nor accepted as a SPI binding property or similar. Anyway AFAIK I am currently unable to use any drivers as I2S and SPI drivers requires specific idle state which I cannot achieve without driver changes. |
Ok, so how will users be able to use adressable leds with (for example) the NXP frdm K64 board? This one suffers from the same "idle high" complication with SPI and I2S. |
Idle is high if output is active low.
Hold idle inactive for full reset duration before sending strip data to ensure initial data is not corrupted.