cancel
Showing results for 
Search instead for 
Did you mean: 

DMA1_Channel1_IRQHandler() is not getting triggered

kb24
Senior

Hello, I am using STM32G030F6Px, it has 32 KB flash memory and I need free space to save data in flash, also it needs to have bootloader. That's why I decided to use bare metal code instead of HAL library, of course I did this by examining HAL libraries. I could set system clock to 64 MHz, also I could use UART with interrupts, timers with interrupts and PWM. Until this point I was successful, 15 KB library code became 2.5 KB. Then I tried to add ADC with DMA. I created this "uint32_t adcValues[2]" variable and gave it to DMA. I put breakpoint in DMA1_Channel1_IRQHandler but it never comes here in the debug session. When I suspend it in anywhere else I see I can get correct analog values from "adcValues[2]". I did same project with HAL libraries and in there DMA1_Channel1_IRQHandler gets triggered. In the debug session I compared the registers and its all same. I set Bit 4 OVRIE: Overrun interrupt enable for ADC->IER, Bit 3 TEIE: transfer error interrupt enable, Bit 2 HTIE: half transfer interrupt enable, Bit 1 TCIE: transfer complete interrupt enable for DMA->CCR1, also I set NVIC bit for DMA1_Channel1(DMA1 channel 1 interrupt). As I said before register values are same for ADC, DMA, DMAMUX. How can I make DMA1_Channel1_IRQHandler is getting triggered? Sorry for this question with long history, I tried to explain why I cant use HAL libraries.

11 REPLIES 11

Make sure that

  • TC interrupt is enabled in the DMA channel's control register
  • TC status bit is set in DMA status register
  • DMA1_Channel1_IRQ is enabled in NVIC
  • DMA1_Channel1_IRQHandler is properly named and it is properly inserted into the vector table
  • interrupts are enabled globally, and processor is not stuck in some other interrupt with the same or higher priority

JW

Thank you for your reply. I checked first 4 of your advices and those are all correct but I have problem with the last one. I created this project in STM32CubeIde and it provides linker and startup files. There is a section like below in the startup file, and code stuck in there.

LoopForever:

  b LoopForever

 .size Reset_Handler, .-Reset_Handler

/**

 * @brief This is the code that gets called when the processor receives an

 *     unexpected interrupt. This simply enters an infinite loop, preserving

 *     the system state for examination by a debugger.

 *

 * @param None

 * @retval : None

*/

 .section .text.Default_Handler,"ax",%progbits

Default_Handler:

Infinite_Loop:

 b Infinite_Loop

 .size Default_Handler, .-Default_Handler

I couldn't realize that infinite loop is not my for loop in the main. Its my bad sorry. This pictures are from stack.

0693W00000HrYmmQAF.png0693W00000HrYnaQAF.pngI dont have ADC_COMP_IRQHandler, should I have? I checked the project that is created by STM32CubeMX with HAL libraries and it doesn't have ADC_COMP_IRQHandler.

I created something like this and handled interrupt flag0693W00000HrYysQAF.png 

it still goes to infinite loop but this time from different place.0693W00000HrYzMQAV.pngits this

.word CEC_IRQHandler          /* CEC global interrupt          */

TDK
Guru

If it's in the default handler, you probably don't have the interrupt properly defined or inserted into the vector table. Look at the VECTACTIVE bits in SCB_ICSR to determine what interrupt it's in, then make sure you've implemented it correctly.

There is some possibility it's not linked properly. If you're using C++, it needs C linkage. GCC also has a linker bug related to weakly defined interrupts.

If you feel a post has answered your question, please click "Accept as Solution".

> GCC also has a linker bug related to weakly defined interrupts.

This is new to me. Can you please tell me more.

JW

Hmm, I searched for 5 minutes but couldn't turn anything up online. I am sure there is a GCC linker bug report about it but I cannot find it now.

The issue was that the weakly defined symbols in the startup file were not being overwritten by the strongly defined functions within the source file. I believe the linker found the weak definition first and stopped checking for another definition. I believe it was only a problem with LTO or similar optimization.

This leads to all interrupts being serviced by Default_Handler instead of their intended handlers.

It was not a common bug, but I have personally experienced it so am as sure as I can be that it exists/existed. Removing the weak definitions fixes the issue. Possibly is fixed with newer GCC versions.

Now that I look closer, probably not the issue here as LoopForever is being called, not the functionally similar. Default_Handler.

If you feel a post has answered your question, please click "Accept as Solution".

@Community member​ Found it. Here is the bug tracker report about it:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83967#c11

If you feel a post has answered your question, please click "Accept as Solution".

Interesting. Thanks.

JW

Here is some more information:

https://bugs.launchpad.net/gcc-arm-embedded/+bug/1747966

Indeed the bug manifested itself only with LTO turned on. It was fixed in GNU Binutils 2.35 and consequently in GNU Arm Embedded Toolchain 10-2020-q4-major.