cancel
Showing results for 
Search instead for 
Did you mean: 

DMA interrupt suddently does not fire

patrickbrataas9
Associate II
Posted on January 21, 2014 at 03:09

I have quite a big code, I might post it(part of it) at a later point, but first I wanted to ask if anyone can think of any reason why my microcontroller does not fire a DMA interrupt when the only thing I do is remove the debug print? And when I comment it back in again everything works just great!

Debug output is just a simple printf() that uses UART. DMA had nothing to do with the UART, but with the ADC. The DMA is triggered when x number of samples have been sampled and a timer is triggering the sampling. I can see when debugging that the timer ISR is triggered, but DMA is never. I can also confirm that the ADC samples on the timer ISR is actually sampling (looked at data while debugging).

I know this is very general/abstract, but I have been debugging this for days and need some input on what might cause this..
9 REPLIES 9
Posted on January 22, 2014 at 09:04

How do you know that the DMA interrupt stopped firing?

You might also want to step back and write a simple test program, rather than fight with the complexity of your whole application.

JW

patrickbrataas9
Associate II
Posted on January 22, 2014 at 18:08

I have a breakpoint in the DMA ISR and I have a flag that is set in this DMA ISR that is never set.

I am currently doing major refactoring and simplification of the code and hope this will make it easier to debug this problem. So far I have it running even without debugprint, but it stops sometime between 5 sec and a few minutes and if I disable the DAC (which is not even used) it works for hours. I have a feeling it might be a hardware problem (current draw or something).

I will try debug until im out of ideas and post code.

chen
Associate II
Posted on January 23, 2014 at 11:30

''I have a breakpoint in the DMA ISR''

That is a terrible way to debug ISR firing problems!

''I have a flag that is set in this DMA ISR that is never set.''

This will only debug the ISR firing once. A counter will be better.

Try using a IO line as an output. In the ISR, toggle this line and watch it with an oscilloscope.

If you want to know how long the ISR takes: set and clear the IO line on entry/exit. (There will be a little error in this due to HW ISR latency and additional ISR code inserted by the compiler)

patrickbrataas9
Associate II
Posted on January 24, 2014 at 23:48

I have used counters and the result can be seen in the picture below. There are two almost identical codes running in the same program that use a separate DMA, TIM and ADC. The ADC sample on TIM CC and DMA transfers the adc samples and signals when transfer is complete.

Sometimes when waiting for the DMA transfer complete interrupt (in a while-loop), it never gets signaled. This is the case for both the DMA ISRs I have in my program. In the picture below one of them (

DMA2_Channel4_5_IRQHandler

)

suddently did not fire the 11438th time. The timer that belongs to DM2CH4_5 (

TIM8_CC_IRQHandler

) continues to fire interrupts, butI can not confirm if the ADCstilldoes sample. The DMA does increment the pointer to the memory location to save the sampled data, but I can not see that any of the data in thesample buffer is every overwritten. This might mean there is a problem with the ADC and/or the DMA. Any suggestions on how to debug this further? I do have some thoughts about the value that is being read continuously in the while loop. This value is written in the DMA ISR. To make sure they do not access the global variable at the same time I have currently done this:

bool_t DMA_IsTransferDone(DMA_t * dma) 
{ 
bool_t temp; 
__disable_irq(); 
temp = dma->isTransferDone; 
__enable_irq(); 
return temp; 
}

Could this cause any problems? (I will at a later time onlydisablethe ISRsaccessing this variable). Image link:

http://itinypic.com/mczxo6.png

Posted on January 25, 2014 at 01:44

Make sure variables set in interrupts are volatile, you shouldn't need to disable/enable interrupts for a read, it's going to be atomic, as are writes. Avoid RMW.

Don't do this if-then-else construct in the interrupt, multiple bits can be set and should be serviced regardless of the state of other bits.

Is the ADC throwing a DMA Overrun error?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on January 25, 2014 at 14:36

IMO it's all too complex, and you might be lost in the complexity.

What's DMA_GetAdc3Struct() , for example?

As an experiment, try to replace the whole pointerish-structurish-shebang you use to signal to main that the interrupt has fired, with one single plain global volatile variable.

JW
patrickbrataas9
Associate II
Posted on January 25, 2014 at 14:57

I have done as you said, but problem is still there.

I am running this on a STM32F103 and as far as I can see it does not have an ADC overrun flag (which would be really helpful to figure out if its DMA or ADC, I think ADC as the ADC sample buffer values do not get updated when Timer is still running when spinning in the while loop).

The DMA also has the highest IRQ priority of all interrupts.

More suggestions are very much appreciated as I am stuck here =/

patrickbrataas9
Associate II
Posted on January 25, 2014 at 15:39

Tried it, still does not change anything. Currently it seems like only my DMA2 is stopping. When I disable it the code runs fine (tested it for 20minutes+ twice and never stopped).

Posted on January 27, 2014 at 08:17

IMO it's time to produce a minimal, but complete compilable example, perhaps containing code only for the Timer/ADC/DMA and a simplistic main loop, and if it still exhibits the problem, publish it here, so that others can try to reproduce it.

JW