Showing results for 
Search instead for 
Did you mean: 

HAL_DAC_Start_DMA doesn't correctly display audio.

Associate II

I wanted to use DAC with DMA with TIM5 being the trigger. my problem is that it does not correctly display the audio,

I mean the original audio is like 10 seconds, I first tried to do the transfer by the CPU so that for every interrupt generated by the TIM5, I wrote a code in the callback function to transfer one byte from audio to DAC. and here is the result waveform:






it was like 11-second audio. but anyways, I think the DAC outputted the audio correctly, but when I made the DMA handle this, here was the result:





it seems like it doesn't wait for any update event from TIM5 but rather keeps changing the DAC output with the next byte from audio as fast as possible and so the result audio is like 1.6 seconds, so any guesses where could the problem be?

I tried to change my TIM5 frequency by changing period, clock division but nothing changes


There are examples of using TIM to trigger DMA/DAC in the CubeMX repository. Take a look at those and compare your code.


If you feel a post has answered your question, please click "Accept as Solution".
Associate II
I discovered the problem but don't know how to solve it, according to the reference manual, the NDTR register which holds how many bytes to be transferred has a maximum value of 65535 while my audio size was about 463562, so after a lot of debugging I discovered that when 463562 got written into the NTDR register, it's actually truncated as :
463562 in binary is 0111 0001 0010 1100 1010
while the actual value written to the NTDR register is 0001 0010 1100 1010 so the last 4 bits got truncated and the actual number of data transferred from the memory to DAC is 4810, it's just a shame that ST didn't mention any of that in their HAL docs especially when the length of data that's supplied to the API is of size 32-bit, I discovered that after debugging the HAL libraries.
Chief II

This just shows for the millionth time that firmware code cannot be written without reading the reference manual.

As for how to solve it... What would you do, if you had to transfer a terabyte of data? Wait until there is a microcontroller with a terabyte of RAM? And what about a continuous stream? The answer is obvious - you split the data into packets. And you implement a double buffering - while one of the packets is played, the other one is read/processed or otherwise prepared for playback.