cancel
Showing results for 
Search instead for 
Did you mean: 

Code stop running at NVIC_EnableIRQ

HTess.1
Associate III
#define HWREG(x)    (*((volatile uint32_t *)(x)))
int dataFromRegister = 0;
void EXTI9_5_IRQHandler();
void GPIOH_Port15_Toggle();
void GPIOH_Init();
void GPIOK_Port5_Toggle();
void GPIOK_Init();
void SystemCLCKInit();
void setup() {
  // put your setup code here, to run once:
  /**********Enable Clock**************/
  SystemCLCKInit();
  // enable clock for system configuration
  SET_BIT(RCC->APB4ENR, RCC_APB4ENR_SYSCFGEN_Msk);
  delay(1000);
  // enable clock for GPIO PORTH on AHB bus
  SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOKEN_Msk);
  delay(1000);
  // enable clock for GPIO PORTK on AHB bus
  SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOHEN_Msk);
  delay(1000);
  /************SETUP PORTH15****************/
  GPIOH_Init();
  digitalWrite(LEDB,LOW);
  delay(1000);
  /*************SETUP PORTK1***************/
  GPIOK_Init();
  digitalWrite(LEDB,HIGH);
  delay(1000);
  digitalWrite(LEDG,LOW);
  delay(1000);
  /************Interruption****************/
  //CONF EXTI
  SET_BIT(EXTI->IMR1, EXTI_IMR1_IM5_Msk);
  SET_BIT(EXTI->RTSR1, EXTI_RTSR1_TR5_Msk);
  CLEAR_BIT(EXTI->FTSR1, EXTI_FTSR1_TR5_Msk);
  //CONF SYSCFG
  SYSCFG->EXTICR[2] |= SYSCFG_EXTICR2_EXTI5_PK;
  //CONF NVIC
  NVIC_EnableIRQ(EXTI9_5_IRQn);
  NVIC_SetPriority(EXTI9_5_IRQn,1);
  
  digitalWrite(LEDG,HIGH);
  delay(1000);
  digitalWrite(LEDB,LOW);
  delay(1000);
  //NVIC_SetPriority(23);
  
  
}
 
void loop() {
  // put your main code here, to run repeatedly:
  GPIOK_Port5_Toggle();
}
 
void EXTI9_5_IRQHandler(void) {
  //Serial.println("IT");
  //delay(20);
  digitalWrite(LEDB,LOW);
  if (EXTI_PR1_PR5 & EXTI_PR1_PR5_Msk == 1) {
    GPIOH_Port15_Toggle();
    digitalWrite(LEDG,LOW);
    SET_BIT(EXTI->PR1,EXTI_PR1_PR5_Msk);
  }
 
}
void GPIOK_Init(void) {
  SET_BIT(GPIOK->MODER, GPIO_MODER_MODE5_0);
  CLEAR_BIT(GPIOK->MODER, GPIO_MODER_MODE5_1);
  CLEAR_BIT(GPIOK->PUPDR, GPIO_PUPDR_PUPD5_1);
  SET_BIT(GPIOK->PUPDR, GPIO_PUPDR_PUPD5_0);
  SET_BIT(GPIOK->BSRR, GPIO_BSRR_BS5);
  CLEAR_BIT(GPIOK->BSRR, GPIO_BSRR_BS5);
}
void GPIOK_Port5_Toggle(void) {
  SET_BIT(GPIOK->BSRR, GPIO_BSRR_BS5);
  CLEAR_BIT(GPIOK->BSRR, GPIO_BSRR_BS5);
  delay(1000);
  SET_BIT(GPIOK->BSRR, GPIO_BSRR_BR5);
  CLEAR_BIT(GPIOK->BSRR, GPIO_BSRR_BR5);
  delay(1000);
}
void GPIOH_Init(void) {
  SET_BIT(GPIOH->MODER, GPIO_MODER_MODE15_0);
  CLEAR_BIT(GPIOH->MODER, GPIO_MODER_MODE15_1);
  CLEAR_BIT(GPIOH->OTYPER, GPIO_OTYPER_OT15);
}
void GPIOH_Port15_Toggle(void) {
  digitalWrite(LEDB,HIGH);
  SET_BIT(GPIOH->BSRR, GPIO_BSRR_BS15);
  CLEAR_BIT(GPIOH->BSRR, GPIO_BSRR_BS15);
  SET_BIT(GPIOH->BSRR, GPIO_BSRR_BR15);
  CLEAR_BIT(GPIOH->BSRR, GPIO_BSRR_BR15);
}

I am trying to use EXTI on GPIOK port 5 (LEDR for my portenta with microcontroller STM32H747) after using my LEDs to check where my code was stuck I noticed that it stopped running after NVIC_EnableIRQ(EXTI9_5_IRQn). I first supposed that the IT was immediately triggered and my code was stuck in the IT routine but since my blue led isn't triggered I guess I don't enter my Interrupt routine (also it is on a rising edge of the GPIOK so it shouldn't be triggered as my GPIO is in a LOW state after init). Is it linked to the __enable_irq() CMSIS function if it is how do I use it? I also read about defining the vector table (VTOR registers in the programming manual) but that shouldn't be the problem since my vector table is defined within a linker file, do I need a double definition?

1 ACCEPTED SOLUTION

Accepted Solutions
HTess.1
Associate III

I forgot the NVIC_SetVector() line.

View solution in original post

8 REPLIES 8
TDK
Guru

> if (EXTI_PR1_PR5 & EXTI_PR1_PR5_Msk == 1)

This is never true, as EXTI_PR1_PR5_Msk != 1. Your code enters the interrupt and then keeps re-entering it because you never clear the flag. Use this instead:

if (EXTI_PR1_PR5 & EXTI_PR1_PR5)

Debugging your code and stepping through would have caught this.

> SET_BIT(EXTI->PR1,EXTI_PR1_PR5_Msk);

You don't need a read-modify-write here. In fact, in doing so you're clearing all present flags and not just the one you want to clear. Write only the bit you want to clear and save a few cycles.

EXTI->PR1 = EXTI_PR1_PR5;

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

Thanks for your answer however it doesn't seem to be the solution (I do not deny that what I wrote was false but the main issue does not come from here) also if it did go within the interrupt routine EXTI9_5_IRQHandler(void) my blue LED should have turned on which was not the case, unless the Interrupt handler code is read only if the :

    if (EXTI_PR1_PR5 & EXTI_PR1_PR5)

condition is verified. So considering all that could it be possible that my Interrupt Handler is not defined as EXTI9_5_IRQHandler (leading to the flag never being cleared), I am pretty sure they kept the same handler name since in the CMSIS file I use very few handler need ALIASES for transition between STM32 components...

As for debugging well on Arduino IDE not sure I have many possibilities apart from using LEDs as checkpoints and then print through serial the registers where there seems to be an issue.

> if (EXTI_PR1_PR5 & EXTI_PR1_PR5)

Oh, multiple errors. You don't actually check the register in there. You need to check the register and not a constant. I missed that before.

if (EXTI->PR1 & EXTI_PR1_PR5)

"EXTI9_5_IRQHandler" is the proper name. If you're in C++, it will need to be declared with extern "C" to have the proper linkage. You can verify by looking at the map file, or startup script where the vector entries are defined.

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

Still doesn't solve the problem ... I am starting to expect that I have done some really dumb mistake... But I can confirm the issue comes from the code being stuck in the IT routine (EXTI->PR1=0x20). I am going to go back to read the Ref Manual I might have missed a clock somewhere. Can it be linked to NVIC1 and NVIC2 since I don't think I have defined which NVIC CPU I use for Interrupts.

Debug, run and wait for code to "stop running", hit pause, see where the code is at. If it stops after you enable an IRQ, the most logical explanation is that it's in an interrupt. Perhaps not the one you expect it to be in. Perhaps the default handler, in which case it will re-enter ad nauseam.

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

I forgot the NVIC_SetVector() line.

Hi, my code is misbehaving, too. I figured it could be because of your NVIC_SetVector() line. But the command is not working for me;

NVIC_SetVector(EXTI15_10_IRQn, (uint32_t)&EXTI15_10_IRQHandler);
NVIC_EnableIRQ(EXTI15_10_IRQn);

I get the error that EXTI15_10_IRQHandler undeclared, first use in this function.

How did you implement it?

Start a new thread, stating what hardware are you using, what is the software, what are the expectations and how are the observed symptoms different from them.

JW