i2s_out: Fix i2s_start -> tx rempty -> i2s_done#128
Conversation
… stats_out_timer_start
| // let's hope that the EOF frame is always zeroes, and zero bytes at the start are harmless... | ||
| i2s_ll_tx_start(i2s_out->dev); | ||
|
|
||
| // can only be enabled once tx is running, will otherwise always fire immediately |
There was a problem hiding this comment.
Speculation: the premature tx rempty interrupts before DMA EOF might happen if DMA hasn't had a chance to put anything into the TX FIFO before i2s_out_i2s_start() starts I2S TX?
Testing shows that the i2s_intr_enable() -> i2s_ll_tx_start() ordering will always fire:
W (1522) i2s_intr_tx_rempty_handler: tx rempty i2s_start=1 dma_done=0 i2s_done=0
W (1552) i2s_intr_out_eof_handler: re-enable tx rempty interrupt
W (1552) i2s_intr_tx_rempty_handler: tx rempty i2s_start=1 dma_done=0 i2s_done=0
W (1582) i2s_intr_out_eof_handler: re-enable tx rempty interrupt
W (1582) i2s_intr_tx_rempty_handler: tx rempty i2s_start=1 dma_done=0 i2s_done=0
W (1602) i2s_intr_out_eof_handler: re-enable tx rempty interrupt
W (1602) i2s_intr_tx_rempty_handler: tx rempty i2s_start=1 dma_done=0 i2s_done=0
W (1632) i2s_intr_out_eof_handler: re-enable tx rempty interrupt
W (1632) i2s_intr_tx_rempty_handler: tx rempty i2s_start=1 dma_done=0 i2s_done=0
W (1662) i2s_intr_out_eof_handler: re-enable tx rempty interrupt
There was a problem hiding this comment.
This also happens if calling i2s_out_i2s_start() -> i2s_out_dma_start().
W (1832) i2s_intr_out_eof_handler: re-enable tx rempty interrupt
W (1842) i2s_intr_tx_rempty_handler: tx rempty i2s_start=1 dma_done=0 i2s_done=0
W (1862) i2s_intr_out_eof_handler: re-enable tx rempty interrupt
W (1872) i2s_intr_tx_rempty_handler: tx rempty i2s_start=1 dma_done=0 i2s_done=0
W (1892) i2s_intr_out_eof_handler: re-enable tx rempty interrupt
W (1902) i2s_intr_tx_rempty_handler: tx rempty i2s_start=1 dma_done=0 i2s_done=0
W (1932) i2s_intr_out_eof_handler: re-enable tx rempty interrupt
W (1932) i2s_intr_tx_rempty_handler: tx rempty i2s_start=1 dma_done=0 i2s_done=0
W (1962) i2s_intr_out_eof_handler: re-enable tx rempty interrupt
W (1962) i2s_intr_tx_rempty_handler: tx rempty i2s_start=1 dma_done=0 i2s_done=0
There was a problem hiding this comment.
This is a good thing, because the i2s out TX is likely to harmless at the very start of the transfer. But fixing this race would make the premature tx rempty intr warning more relevant, if some kind of memory contention causes the DMA to stall enough for the TX FIFO to empty during the frame and disrupt the WS2812B timings? Maybe we could even use i2s_ll_tx_stop_on_fifo_empty() / tx_stop_en?
Fixes #127
Do not enable
I2S_TX_REMPTY_INT_ENAon the DMA EOF interrupt beforei2s_out_i2s_start(), this can currently lead to on assert failure on thestats_timer_update()call withstats_out_timer_startunset. Observed with a very small[leds] count = 10config, making this more likely.Improve the opt-in ISR WARN logging and guard against these kinds of conditions. Drop the missed EOF descr logging to INFO, because this is expected to happen with short descrs.
Tweak the ordering of the state update, ll dev setup and interrupt enable/disable in the critical sections.