0

On the Stm32f4-Discovery board I've configured the tripple ADC Interleaved mode with DMA writing the ADC data in circular mode 2. Everything works fine, but I can't pause the transfer properly to transfer the data in the buffer through USART (the transform is performed inside an external interrupt vertor function). I am trying to implement such an algorithm:

  1. Initialize DMA and ADCs
  2. Wait for an external interrupt
  3. Pause the DMA transfer
  4. Send the buffered data through USART
  5. Resume the DMA transfer, goto step 2

One thing I tried was

DMA_Cmd(DMA2_Stream0, DISABLE);
ADC_Cmd(ADC1, DISABLE); ADC_Cmd(ADC2, DISABLE); ADC_Cmd(ADC3, DISABLE);
... Send the buffered data over USART ...
ADC_Cmd(ADC1, ENABLE); ADC_Cmd(ADC2, ENABLE); ADC_Cmd(ADC3, ENABLE);
DMA_Cmd(DMA2_Stream0, ENABLE);

That's fine, but at some point the DMA just becomes stuck at the first bit and does not "move" through all the buffer array. I've also tried just stopping the RCC Clocks for the ADCs

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, DISABLE); //So on for ADC2 and ADC3

But it does the same, the only difference is that the first method stops the DMA transfer at some point (therefore, sometimes it pauses the DMA normally), and the second method stops the DMA never works okay.

I also read in the reference manual that

If the conversion sequence is interrupted (for instance when DMA end of transfer occurs), the multi-ADC sequencer must be reset by configuring it in independent mode first (bits DUAL[4:0] = 00000) before reprogramming the interleaved mode.

I've tried setting the ADC to the independent mode when pausing and then setting the ADC to the tripple interleaved mode in both methods described above, but that did not change the situation a bit.

So, the question is - what is the right way to pause the DMA transfer, so that the buffered data that I am trying to send over USART does not change?

artless noise
  • 21,212
  • 6
  • 68
  • 105
sx107
  • 309
  • 3
  • 11
  • Have you tried just disabling the DMA with the `DMA_Cmd()`? I see you do that plus changing the ADC configs, but I'm wondering if you just disable the DMA in the DMA peripheral and then re-enable it, if that will give you the behavior that you want. – rjp Sep 12 '16 at 18:16
  • @rjp Yes, I've tried that already. Didn't help at all - the DMA still stops (it becomes stuck at the first buffer position) – sx107 Sep 14 '16 at 12:59
  • Is it possibly a case where after re-enabling every time, you have to manually start a conversion to "prime the pump" so to speak? I know this is sometimes needed on things like transmit DMAs. Does the DMA's enable need to be set before the ADC's DMA? – rjp Sep 14 '16 at 13:20
  • @rjp Do you mean starting a software convertion? Haven't tried that yet, I will reply later if it will help. The order of DMA and ADC enabling doesn't matter, as I remember. – sx107 Sep 14 '16 at 13:26
  • I found the following snippet: `DMA_Cmd(DMA2_Stream0, DISABLE); DMA_SetCurrDataCounter(DMA2_Stream0,768); DMA_Cmd(DMA2_Stream0, ENABLE);` on this German website. http://www.mikrocontroller.net/topic/292963 Perhaps you need to reset the counter like they are doing? – rjp Sep 14 '16 at 13:43
  • @rjp I have tried restarting the ADC (starting a software convertion), and it helped, thank you very much! Other methods haven't changed the situation at all. – sx107 Sep 16 '16 at 15:28
  • does that mean everything is working for you now? Or are you still having other issues? – rjp Sep 16 '16 at 17:19
  • @rjp Yes, everything works fine. Thank you very much. I used the first method in the OP message with the software convertion starting. – sx107 Sep 16 '16 at 17:51

0 Answers0