Make sure DMA buffer is zeroed in 32 bits mode. (AUD-594) #110
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
DMA buffers for I2S must be set to zero to prevent noise after playback stops. This works well in 16 bits mode. In 32 bits mode leaves some samples in the buffer and these samples repeat.
The existing code created a buffer of four times the number of samples in the DMA buffer. I think this is a hardcoded assumption of 16bits stereo (4 bytes per sample).
i2s->config.i2s_config.dma_buf_len * 4
The number of bytes in the DMA buffer cannot be reliably calculated. The logic is non-trivial (max 4096, etc.). It turns out that the I2S library already have a function to zero the buffer
i2s_zero_dma_buffer
. When I calli2s_zero_dma_buffer(i2s->config.i2s_port);
instead ofi2s_write(i2s->config.i2s_port, (char *)buf, i2s->config.i2s_config.dma_buf_len * 4, &bytes_written, portMAX_DELAY);
I get no noise, neither in 16 or 32 bits mode.There is a test on
i2s->config.i2s_config.mode & I2S_MODE_DAC_BUILT_IN
that sets the buffer to0x80
instead of0x00
. I left this branch as it was withi2s_write
instead ofi2s_zero_dma_buffer
, but I have not been able to test that there are no regression with theI2S_MODE_DAC_BUILT_IN
.