Skip to main content
kb24
Senior
January 13, 2022
Question

DMA1_Channel1_IRQHandler() is not getting triggered

  • January 13, 2022
  • 4 replies
  • 4122 views

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.

This topic has been closed for replies.

4 replies

waclawek.jan
Super User
January 13, 2022

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

kb24
kb24Author
Senior
January 13, 2022

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.

kb24
kb24Author
Senior
January 13, 2022

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
Super User
January 13, 2022

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""."
waclawek.jan
Super User
January 13, 2022

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

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

JW

TDK
Super User
January 13, 2022

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""."
kb24
kb24Author
Senior
January 14, 2022

I am so sorry to all of you. It was all my mistake. In the startup file function name was DMA_Channel1_IRQHandler instead of DMA1_Channel1_IRQHandler. When I changed that it worked. Thanks to this silly question I learned what can cause interrupt to not get fired and VECTACTIVE bits so I can understand a function is called from thread mode or interrupt handler if yes which interrupt handler. I hope it helps others. Thanks a lot.