cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 TIM6 interruption doesn't happen while DMA working

kozlovdmn
Associate II
Posted on December 22, 2016 at 10:14

I work with STM32F4Discovery board, generate code from Cube, SYSCLK is 168MHz, APB1 Timer Clock 42 MHz, TIM6 has prescaler 1000, and counts till I make the following experiment.

Enable TIM6 interruption by

 __HAL_TIM_ENABLE_IT(&htim6, TIM_IT_UPDATE); 
 HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);

Start DAC_DMA in normal mode with 30-elements array.

Count how many timer interruptions happen

 void TIM6_DAC_IRQHandler(void) { 
 HAL_TIM_IRQHandler(&htim6);

 tim6Counter++; }

Set breakpoint in this function:

 void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac) {
 conversionCounter++; }

What I expect:

1) HAL_DAC_ConvCpltCallbackCh1 is called once (due to noncircular mode). It is true.

2) When it's called tim6Counter has to be equal 30, as length of DAC data buffer is In experiment tim6Counter is 1.

3) After DAC is completed, set breakpoints to TIM6 handler, and to main while(1) loop. The problem is, that it hangs in TIM6 handler.

Questions:

1) DMA works even if TIM6 interruptions are not enabled. But if enabled, why it happens only once, instead of every DMA request?

2) Why it hangs in timer handler?

3) TIM6 SR register is not cleared, either by HAL macros, or by HAL_TIM_IRQHandler. I use eclipse with openOCD. Is it a problem of tools? Or due to hanging in handler?

UPD. Problem is, that timer still counts during debug pause. After switching timer to debug mode, it works properly.

#hang #dma #interrupts #tim
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on December 22, 2016 at 12:53

I see.

Can't that be that it hands in the TIM6 ISR handler right away, and never leave it? DMA would work regardless, and if its ISR is of higher priority it will kick in in due time.

I don't Cube so I don't know who's responsible for clearing the TIM6_SR. Note, that if you don't set the appropriate bit in DBGMCU freeze registers (or the debugger does not do that for you through some its 'magic', which any sane debugger wouldn't, I hope), the timer continues to run and throw flags during the time while processor is stopped (e.g. in single-stepping), so from the slow human's point of view the timer's status bits might appear to be set permanently.

JW

View solution in original post

4 REPLIES 4
Posted on December 22, 2016 at 10:29

When it's called tim6Counter has to be equal 30, as length of DAC data buffer is 30. In experiment tim6Counter is 1.

Why? Do you actually trigger DAC from TIM6TRGO, i.e. do you have DAC_CR.TENx set?  You can verify it easily by outputting a square-wave from the DAC and observing it by an oscilloscope - you should see 30 level changes, TIM6-overflow-period apart.

JW

Posted on December 22, 2016 at 12:26

You are right, TIM6 is a trigger source for DAC. Every upload event new DAC value is generated. (I've checked the period, it is 1.5 ms, as it has to be.)

I expect, that number of update events and number of interruptions have to be the same. Now it is not like that.

Posted on December 22, 2016 at 12:53

I see.

Can't that be that it hands in the TIM6 ISR handler right away, and never leave it? DMA would work regardless, and if its ISR is of higher priority it will kick in in due time.

I don't Cube so I don't know who's responsible for clearing the TIM6_SR. Note, that if you don't set the appropriate bit in DBGMCU freeze registers (or the debugger does not do that for you through some its 'magic', which any sane debugger wouldn't, I hope), the timer continues to run and throw flags during the time while processor is stopped (e.g. in single-stepping), so from the slow human's point of view the timer's status bits might appear to be set permanently.

JW

Posted on December 22, 2016 at 14:25

You are completely right. I hasn't known, that timer counts during breakpoint pause (I have missed 'Debug mode' Timer section in reference manual). After freezing everything is correct. Thanks a lot.