cancel
Showing results for 
Search instead for 
Did you mean: 

DMA: Start transfer from address + offset

GChri.2
Associate II

Hi, 

I want to use my F072's DACs to output a sin and cos signal. to save on memory I want to have only one buffer holding the values of a SIN function, COS values should be taken from the same buffer. Basically, I need the DMA for channel 1 to start from the beginning of the buffer and for channel 2 to start at an offset. Of course, I can't just do something like 

HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, lut, no_samples, DAC_ALIGN_12B_R);
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, lut + no_amples / 4, no_samples, DAC_ALIGN_12B_R);

because that would make the dma access elements outside the buffer. 

in the reference manual I found the register DMA_CNDTRx register, is this the way to go? 

1 ACCEPTED SOLUTION

Accepted Solutions
waclawek.jan
Super User

There's no simple way to achieve this.

> DMA_CNDTRx register

That is written by the total number of items to be transferred (4th parameter in the Cube/HAL function you are using).

You haven't given us enough information, so I'm going to make some assumptions: both channels are set in Circular mode, triggered from the respective DAC channels, and the DAC channels are triggered from a timer.

What you should do is basically having one of the channels (the cos one) seen (no_samples+4) triggers before you enable the second channel. One way to do it is to start the cos channel together with a timer, the timer set so that it will throw an interrupt exactly at the (no_samples+4)-th sample, and start the sin channel there.

I personally would set up everything (DACs, DMAs, timer) except starting the timer, temporarily change the cos channel to software trigger, in software loop generate (no_samples+4), switch that channel back to trigger from the timer and after that start the timer. This may be harder to do in Cube/HAL, though; I don't use Cube/HAL.

JW

View solution in original post

2 REPLIES 2
waclawek.jan
Super User

There's no simple way to achieve this.

> DMA_CNDTRx register

That is written by the total number of items to be transferred (4th parameter in the Cube/HAL function you are using).

You haven't given us enough information, so I'm going to make some assumptions: both channels are set in Circular mode, triggered from the respective DAC channels, and the DAC channels are triggered from a timer.

What you should do is basically having one of the channels (the cos one) seen (no_samples+4) triggers before you enable the second channel. One way to do it is to start the cos channel together with a timer, the timer set so that it will throw an interrupt exactly at the (no_samples+4)-th sample, and start the sin channel there.

I personally would set up everything (DACs, DMAs, timer) except starting the timer, temporarily change the cos channel to software trigger, in software loop generate (no_samples+4), switch that channel back to trigger from the timer and after that start the timer. This may be harder to do in Cube/HAL, though; I don't use Cube/HAL.

JW

your assumption was correct. 

thank you for your suggestion, that may be a viable option, and would also allow me to implement an arbitrary offset between the channels, if necessary at some point.