the gap between DAC DMA stop and start
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-01-20 2:03 AM
Hi all
I know the question title sounds weird but here is the actual thing I would like to know about.
So, I have an array of 1000 bytes which I apparently use in the HAL_DAC_START_DMA function, and then start the DAC DMA trigger timer. This works super fine and on the half-complete callback of DAC DMA I read the next 1000 bytes from a file inside the SD-Card and on complete DAC DMA callback, I simply stop the trigger timer, stop the DAC DMA and reload the new 1000 bytes into HAL_DAC_START_DMA function and start the timer again.
// audio out function main bits
memset((void *) DacAudioBuffer.Audio16BitBuffer, 0, sizeof(DacAudioBuffer.Audio16BitBuffer));
memcpy((void *) DacAudioBuffer.Audio16BitBuffer, (void *) DacAudioBuffer.Temp16AudioBuffer, sizeof(DacAudioBuffer.Temp16AudioBuffer));
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t *) DacAudioBuffer.Audio16BitBuffer, BuffSize, DAC_ALIGN_12B_R);
HAL_TIM_Base_Start_IT(&htim2);
// DAC DMA half out call back
IsDacDataHalfOut = TRUE;
// DAC DMA complete call back
if(HAL_TIM_Base_Stop_IT(&htim2) == HAL_OK) {
if(HAL_DAC_Stop_DMA(hdac, DAC_CHANNEL_1) == HAL_OK) {}
IsDacDataCpltOut = TRUE;
}
The main problem I'm facing is that there is a gap between when I stop the timer and restart it again (a big gap in msec) which I don't like to happen.
The bytes I'm reading from the file are audio bytes of wave file so they need to be stitched together perfectly but as soon as time passes the gap becomes bigger and bigger. Any help would be very appreciated. Thanks
- Labels:
-
DAC
-
DMA
-
STM32CubeIDE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-01-20 3:42 AM
The usual way to produce continuous waveform is to use DMA in CIrcular mode (i.e. never stop), and feed the opposite (unused) half of the buffer (i.e. the first half in the HalfComplete interrupt, and the second half in the TransferComplete interrupt), while DMA is playing back from the other half of the buffer.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-01-20 4:04 AM
Never heard of this method before but will give it a try and see what happens. Thanks a lot.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-01-20 7:04 AM
Overall Jan's advise is the preferred way. But, if for some reason not possible, then it can be done with single shot DMA and interrupts, it just have to be quick:
- The software must not be bloatware. Therefore no HAL/Cube or other junk code.
- Interrupt has to be of a high priority and almost never disabled.
- ISR must do only DMA disable, buffer swap and DMA enable. No intensive processing there.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-01-20 7:09 AM
Yeah, I know. No junk code in the interrupt but at the moment I'm letting the DMA run forever and seems like my gap problem is resolved. Now I need to implement the half buffer technique which Jan has recommended me so that the very small amount of humming sound I'm getting can be eliminated.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-01-20 7:15 AM
You can't go out to lunch in a callback, it is done under interrupt context.
You need to separate the tasks so you prepare buffers from SD Card in one, and dispatch the half ping-pong output buffer in a continuous/circular DMA operation. ie via a HT/TC interrupt, or double buffer approach.
For SD Card interactions make everything multiples of 512 bytes, and ideally some multiple or sub-multiple of the cluster size.
Up vote any posts that you find helpful, it shows what's working..
