Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drivers: i2s_nrfx: Fix write race condition
There is inherent race condition between i2s_nrfx_write() and I2S interrupt handler because I2S operates independently from the rest of the system. If software takes too long to supply next TX pointer then nRF I2S peripheral will simply resupply the previous buffer. The race window is rather short. The failed race executes as follows: 1. i2s_nrfx_write() checks state and loads next_tx_buffer_needed 2. I2S interrupt handler executes and calls data_handler() which notices empty TX queue and therefore sets next_tx_buffer_needed 3. i2s_nrfx_write() continues with the queue TX path (because the next_tx_buffer_needed was false when it was accessed) If next i2s_nrfx_write() executes before next I2S interrupt: 4a. i2s_nrfx_write() notices next_tx_buffer_needed is true and supplies the buffer directly to I2S peripheral. Previously queued buffer will remain in the queue until the just supplied buffer starts transmitting. Effectively swapping whole I2S block leads to clearly audible artifacts under normal circumstances. If next I2S interrupt executes before next i2s_nrfx_write(): 4b. data_handler() notices that buffer was reused and stops despite having a buffer available in TX queue Modify i2s_nrfx_write() to always queue the TX pointer first and only supply the buffer to nrfx if the queue was empty when interrupt handler executed. This prevents both the out-of-order TX and premature stop. Fixes: #63730 Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
- Loading branch information