Run DAC with DMA for audio - update buffer continuously?
Hi :)
I am trying to play audio from an SD card to the built-in DAC of my Nucleo-F446RE.
I am using DMA, and one buffer of 10240 size, which I want to update continuously using the Transfer Complete / Half Complete callbacks.
The code is quite simple, I simply use the callback to update one half of the buffer while the DMA sends the other half.
#define BUF_SIZE 10240
#define BUF_HALFSIZE (BUF_SIZE/2)
uint8_t llfta_buf[BUF_SIZE];
uint8_t rlfta_buf[BUF_SIZE];
volatile uint8_t updateCh1Part1 = 0, updateCh1Part2 = 0, updateCh2Part1 = 0, updateCh2Part2 = 0;
[...]
int main(void) {
[...]
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)llfta_buf, BUF_SIZE, DAC_ALIGN_8B_R);
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_2, (uint32_t*)rlfta_buf, BUF_SIZE, DAC_ALIGN_8B_R);
HAL_TIM_Base_Start(&htim6);
while (1)
{
UINT readBytes;
if (updateCh1Part1) {
updateCh1Part1 = 0;
f_read(&SDFileLFTALeft, llfta_buf, BUF_HALFSIZE, &readBytes);
}
if (updateCh1Part2) {
updateCh1Part2 = 0;
f_read(&SDFileLFTALeft, llfta_buf+BUF_HALFSIZE, BUF_HALFSIZE, &readBytes);
}
if (updateCh2Part1) {
updateCh2Part1 = 0;
f_read(&SDFileLFTARight, rlfta_buf, BUF_HALFSIZE, &readBytes);
}
if (updateCh2Part2) {
updateCh2Part2 = 0;
f_read(&SDFileLFTARight, rlfta_buf+BUF_HALFSIZE, BUF_HALFSIZE, &readBytes);
}
}
}
void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef* hdac)
{
updateCh1Part2 = 1;
}
void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef* hdac)
{
updateCh1Part1 = 1;
}
void HAL_DAC_ConvCpltCallbackCh2(DAC_HandleTypeDef* hdac)
{
updateCh2Part2 = 1;
}
void HAL_DAC_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef* hdac)
{
updateCh2Part1 = 1;
}I can see in the debugger that the actual buffer gets updated, as it should, but the DAC keeps sending the values that were in the buffer in the first place.
Is that maybe not the wau it was meant to be done? I can see in this document (https://www.stmicroelectronics.com.cn/resource/en/application_note/cd00259245-audio-and-waveform-generation-using-the-dac-in-stm32-microcontrollers-stmicroelectronics.pdf), page 21 that they deactivate and reactivate the DMA each time the buffer is updated, but this will create some pops/cracks in the audio, would it not?
Thanks!
Simon
