cancel
Showing results for 
Search instead for 
Did you mean: 

Pending Register for EXTI line 13 always active

J.v.W.
Associate II

Im trying some bare Metal programming on the NUCLEO - H743ZI2.

Im stuck on creating a Button Interrupt on EXTI line 13.

The User Button 1 is located on PC13, im trying to toggle LED2 on PE1.

LED and Button configuration must be correct, since it works with polling. I think im missing something in the Register configuration for the EXTI, but i cant find the problem. I found no "bare metal" examples for the board im using.

The PR1 register is always at 0x2000 after configuration(bit 13 is set to 1), but only if i activate any of the trigger edge settings. I commented out the RCC and SYSCFG lines in the setup_ISR function and it didnt change the behaviour, so i think im missing something in@ these lines to correctly setup the EXTI. I have tried to find a solution without any succes.

#include <main.h>
 
volatile unsigned char led_on = 1;
uint32_t interrupt = 0;
 
void setup_usrled_2(void)
{
    //LED_PIN = PE1
    // peripheral clock enable
    RCC -> AHB4ENR |= RCC_AHB4ENR_GPIOEEN;
    // 00 overwrite
    GPIOE -> MODER  &= ~(0b11 << (LED_PIN*2)); 
    // 01 output
    GPIOE -> MODER  |=  (0b01 << (LED_PIN*2)); 
    // 0 Open Drain
    GPIOE -> OTYPER &= ~(0b1 << LED_PIN); 
    GPIOE -> PUPDR  &= ~(0b11 << LED_PIN*2); 
}
 
void setup_usrbttn_1(void)
{
    //BUTTON_PIN = PC13
    // peripheral clock enable
    RCC -> AHB4ENR |= RCC_AHB4ENR_GPIOCEN; 
    // 00overwrite == input mode
    GPIOC -> MODER  &= ~(0b11 << (BUTTON_PIN*2)); 
    // 00 overwrite
    GPIOC -> PUPDR  &= ~(0b11 << (BUTTON_PIN*2)); 
    // 10 Pull Down, since USER_B1 is connected to VDD (inactive high)
    GPIOC -> PUPDR  |=  (0b10 << (BUTTON_PIN*2)); 
}
 
void setup_bttn1_ISR(void)
{
    //BUTTON_PIN = PC13
    // peripheral clock enable
    RCC -> APB4ENR |= RCC_APB4ENR_SYSCFGEN;
    // reset EXTI line 13
    SYSCFG -> EXTICR[0] &= ~(SYSCFG_EXTICR4_EXTI13_Msk);
    // activate EXTI line 13 for GPIO Port C (PC13)
    SYSCFG -> EXTICR[0] |=  (SYSCFG_EXTICR4_EXTI13_PC);
    
    // unmask Interrupt for line/interrupt 13
    EXTI -> IMR1 |= (0x01 << EXTI_IMR1_IM13_Pos);
    // deactivate rising trigger (do not react on release of btn)
    EXTI -> RTSR1 &= ~(0x01 << EXTI_RTSR1_TR13_Pos);
    // activate falling trigger (react on press of button)
    EXTI -> FTSR1 |= (0x01 << EXTI_FTSR1_TR13_Pos);
 
    //activate NVIC
    NVIC_SetPriority(EXTI15_10_IRQn, 0x03); 
    NVIC_EnableIRQ(EXTI15_10_IRQn);
}
 
 
void EXTI15_10_IRQHandler(void) 
{
    if (EXTI->PR1 & (1 << BUTTON_PIN)) 
    {
        // clear EXTI status flag
        EXTI->PR1 |= (1 << BUTTON_PIN);
        
        led_on = !led_on;
    }
    NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
}
 
int main(void)
{
    setup_usrbttn_1();
    setup_usrled_2();
    setup_bttn1_ISR();
 
    interrupt = EXTI->PR1;
    while (1) 
    {
        if (led_on)
        {
            GPIOE->ODR |= (1 << LED_PIN);
        }
        else 
        {
            GPIOE->ODR &= ~(1 << LED_PIN);
        }
    }
}

7 REPLIES 7

Read out and check/post content of registers you are trying to work with.

> SYSCFG -> EXTICR[0] &= ~(SYSCFG_EXTICR4_EXTI13_Msk);

> SYSCFG -> EXTICR[0] |= (SYSCFG_EXTICR4_EXTI13_PC);

Are you sure with the [0]?

JW

J.v.W.
Associate II

Sorry for the late response.

First, the registers directly after the setup:

Peripheral Clock for EXTI: RCC->APB4ENR = 0x2 SYSCFG peripheral on

EXTICR4 Register for EXTI line 13: SYSCFG -> EXTICR[4] = 0x2000 line 13 active?

Interrupt Mask Register 1: EXTI -> IMR1 = 0x2000 Interrupt line 13 unmasked

Rising Trigger Register 1: EXTI -> RTSR1 = 0x0 0 Rising off

Falling Trigger Register 1: EXTI -> FTRS1 = 0x2000 Falling Trigger on at line 13

I have also tried replacing the [0] with [4], and changing the GPI/O PIN to PC14 with no change in behaviour. I hope this information helps.

Sorry for the late response.

First, the registers directly after the setup:

Peripheral Clock for EXTI: RCC->APB4ENR = 0x2 SYSCFG peripheral on

EXTICR4 Register for EXTI line 13: SYSCFG -> EXTICR[4] = 0x2000 line 13 active?

Interrupt Mask Register 1: EXTI -> IMR1 = 0x2000 Interrupt line 13 unmasked

Rising Trigger Register 1: EXTI -> RTSR1 = 0x0 0 Rising off

Falling Trigger Register 1: EXTI -> FTRS1 = 0x2000 Falling Trigger on at line 13

I have also tried replacing the [0] with [4] and changing the GPI/O PIN to PC14 with no change in behaviour. I hope this information helps.

https://raw.githubusercontent.com/STMicroelectronics/STM32CubeH7/master/Drivers/CMSIS/Device/ST/STM32H7xx/Include/stm32h743xx.h

__IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */

You want to use SYSCFG -> EXTICR[3] - in RM, EXTICR are 1-based numbered, while in C the array is 0-based.

JW

What a stupid mistake.

I set it to [3] as you told me and it works as intended.

Makes me wonder, why is the EXTICR 1-based. I hope i am not the only one who got confused by it.

> Makes me wonder, why is the EXTICR 1-based.

Because typically the hardware guys do not understand the software and vice versa. Though in ST's case even the software guys do not understand the software. And on top of that the company is too large for the departments to be able to communicate with each other.

By the way, the Julian/Gregorian numbering of years is also 1-based and mathematically flawed:

https://en.wikipedia.org/wiki/Year_zero

> hardware guys do not understand the software

This is compounded by the fact that the 32-bitters these days are not designed in some consistent way, but are slapped together from components (IPs) bought from various vendors.

JW