2

The PC13 EXTI interrupt (EXTI15_10) configured here keeps firing none stop. Most other questions about this same topic indicate that the respective EXTI_PR pending bit needs to be cleared in the ISR. I am clearing the bit in my code.

The nucleo-103rb board connects GPIO PC13 to a user button that I am using to toogle the timer interrupt that blinks the LED between 1 second and .5 second. The board has a debouncer capacitor/resistor, so I don't think a dirty signal is the issue. Even without touching the button, the ISR keeps firing.

Also, in my gdb debug session, if I turn off the edge trigger set *EXTI_FTSR = (unsigned int)0x00000000, the board exits the ISR and settles in the while(1) loop, LED blinking and all. Then, in the debug session, I set an EXTI software pend set *0x40010410 = 0x00002000, then after continuing, the EXTI ISR changes the LED speed and exits back to while(1) without issue.

I can't figuire out why the EXTI ISR keep firing non-stop.

The code:

#define _stackInit 0x20005000U


// RCC base 0x40021000
volatile unsigned int * const RCC_APB2ENR = (unsigned int *)0x40021018; // offset 0x18 APB2ENR
volatile unsigned int * const RCC_APB1ENR = (unsigned int *)0x4002101c; // offset 0x1c APB1ENR

// GPIOA base 0x40010800
volatile unsigned int * const GPIOA_CRL = (unsigned int *)0x40010800;   // offset 0x00 CRL
volatile unsigned int * const GPIOA_ODR = (unsigned int *)0x4001080c;   // offset 0x0c ODR

// GPIOC base 0x40011000
volatile unsigned int * const GPIOC_CRL = (unsigned int *)0x40011000;   // offset 0x00 CRL
volatile unsigned int * const GPIOC_CRH = (unsigned int *)0x40011004;   // offset 0x04 CRH
volatile unsigned int * const GPIOC_IDR = (unsigned int *)0x40011008;   // offset 0x08 IDR
volatile unsigned int * const GPIOC_ODR = (unsigned int *)0x4001100c;   // offset 0x0c ODR

// TIM2 base 0x40000000
volatile unsigned int * const TIM2_CR1 = (unsigned int *)0x40000000;    // offset 0x00 CR1
volatile unsigned int * const TIM2_PSC = (unsigned int *)0x40000028;    // offset 0x28 PSC
volatile unsigned int * const TIM2_DIER = (unsigned int *)0x4000000c;   // offset 0x0c DIER
volatile unsigned int * const TIM2_ARR = (unsigned int *)0x4000002c;    // offset 0x2c ARR
volatile unsigned int * const TIM2_SC = (unsigned int *)0x40000010;     // offset 0x10 SC

// NVIC base 0xE000E100
volatile unsigned int * const NVIC_ISER0 = (unsigned int *)0xE000E100;  // offset 0x00 ISER0
volatile unsigned int * const NVIC_ISER1 = (unsigned int *)0xE000E104;  // offset 0x04 ISER1

// EXIT base 0x40010400
volatile unsigned int * const EXTI_IMR = (unsigned int *)0x40010400;    // offset 0x00 IMR
volatile unsigned int * const EXTI_FTSR = (unsigned int *)0x4001040c;   // offset 0x0c FTSR
volatile unsigned int * const EXTI_PR = (unsigned int *)0x40010414;     // offset 0x14 PR


int c_entry()
{
    // enable GPIOA clock and set PB5 to output
    *RCC_APB2ENR |= (unsigned int)0x00000004;
    *GPIOA_CRL = (unsigned int)0x44244444;

    // enable GPIOC clock and set PC13 to input with pull up
    *RCC_APB2ENR |= (unsigned int)0x00000010;
    *GPIOC_CRH = (unsigned int)0x44844444;


    // enable EXTI on PC13
    *EXTI_IMR |= (unsigned int)0x00002000;
    *EXTI_FTSR |= (unsigned int)0x00002000;

    // enable TIM2 clock and configure the timer interrupt
    *RCC_APB1ENR |= (unsigned int)0x00000001;
    *TIM2_PSC = (unsigned short)0x00ff;
    *TIM2_ARR = (unsigned short)31250u;
    *TIM2_DIER = (unsigned short)0x0001;
    *TIM2_CR1 = (unsigned short)0x0001;

    // enable TIM2 global interrupt in NVIC
    *NVIC_ISER0 |= (unsigned int)(0x01<<0x1c); //0x1c, TIM2 global interrupt position 28

    // enable TIM2 global interrupt in NVIC
    *NVIC_ISER1 |= (unsigned int)(0x01<<0x08); //0x08, EXTI_15_10 interrupt position 40 

    while(1);
    //return 0;
}

void TIM2_IRQHandler()
{
    //toggle PA5
    *GPIOA_ODR ^= 0x20u;
    // clear TIM2 int pending bit
    *TIM2_SC &= ~(unsigned short)0x0001; 
}

void EXTI15_10_IRQHandler()
{
    if (*TIM2_ARR == (unsigned short)31250u){
        *TIM2_ARR = (unsigned short)15625u;
    } else {
        *TIM2_ARR = (unsigned short)31250u;
    }
    *EXTI_PR = (unsigned int)0x00002000;
}


// Begin and End addresses for the .bss section; symbols defined in linker script
extern unsigned int __bss_start__;
extern unsigned int __bss_end__;

void __attribute__ ((section(".after_vectors"))) Reset_Handler (void)
{

    // Initialize bss section by iterating and clearing word by word.
    // It is assumed that the pointers are word aligned.
    unsigned int *p = &__bss_start__;
    while (p < &__bss_end__) {
        *p++ = 0;   
    }

    c_entry();
}

void __attribute__ ((section(".after_vectors"))) Default_Handler(void)
{
    while(1);
}


// cortex-m core exceptions
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) NMI_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) HardFault_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) MemManage_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) BusFault_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) UsageFault_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) SVC_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) DebugMon_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) PendSV_Handler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler"))) SysTick_Handler(void);

// chip level interrupts
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  WWDG_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  PVD_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TAMPER_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  RTC_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  FLASH_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  RCC_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  EXTI0_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  EXTI1_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  EXTI2_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  EXTI3_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  EXTI4_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  DMA1_Channel1_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  DMA1_Channel2_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  DMA1_Channel3_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  DMA1_Channel4_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  DMA1_Channel5_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  DMA1_Channel6_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  DMA1_Channel7_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  ADC1_2_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  USB_HP_CAN1_TX_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  USB_LP_CAN1_RX0_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  CAN1_RX1_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  CAN1_SCE_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  EXTI9_5_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM1_BRK_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM1_UP_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM1_TRG_COM_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM1_CC_IRQHandler(void);
//void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM2_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM3_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM4_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  I2C1_EV_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  I2C1_ER_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  I2C2_EV_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  I2C2_ER_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  SPI1_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  SPI2_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  USART1_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  USART2_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  USART3_IRQHandler(void);
//void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  EXTI15_10_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  RTCAlarm_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  USBWakeUp_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM8_BRK_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM8_UP_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM8_TRG_COM_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM_CC_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  ADC3_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  FSMC_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  SDIO_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM5_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  SPI3_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  UART4_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  UART5_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM6_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  TIM7_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  DMA2_Channel1_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  DMA2_Channel2_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  DMA2_Channel3_IRQHandler(void);
void __attribute__ ((section(".after_vectors"),weak, alias ("Default_Handler")))  DMA2_Channel4_5_IRQHandler(void);


typedef void(* const pHandler)(void);

// The vector table.
// The linker script to place at correct location in memory.

__attribute__ ((section(".isr_vector"),used)) pHandler __isr_vectors[] =
{
    //core exceptions
    (pHandler)_stackInit,   // Inital Stack Pointer
    Reset_Handler,          // reset handler
    NMI_Handler,            // NMI handler
    HardFault_Handler,      // hard fault handler
    MemManage_Handler,      // MPU fault handler
    BusFault_Handler,       // bus fault handler
    UsageFault_Handler,     // usage fault handler
    0x00,                   // reserved
    0x00,                   // reserved
    0x00,                   // reserved
    0x00,                   // reserved
    SVC_Handler,            // SVCall handler
    DebugMon_Handler,       // debug monitor handler
    0x00,                   // reserved
    PendSV_Handler,         // PendSV handler
    SysTick_Handler,        // systick handler

    // chip level interrupts
    WWDG_IRQHandler,            /* Window Watachdog */
    PVD_IRQHandler,             /* PVD EXTI Line Detect */
    TAMPER_IRQHandler,          /* Tamper */
    RTC_IRQHandler,             /* RTC Global */
    FLASH_IRQHandler,           /* Flash Global */
    RCC_IRQHandler,             /* RCC Global */
    EXTI0_IRQHandler,           /* EXTI Line 0 */
    EXTI1_IRQHandler,           /* EXTI Line 1 */
    EXTI2_IRQHandler,           /* EXTI Line 2 */
    EXTI3_IRQHandler,           /* EXTI Line 3 */
    EXTI4_IRQHandler,           /* EXTI Line 4 */
    DMA1_Channel1_IRQHandler,   /* DMA1 Channel1 Global */
    DMA1_Channel2_IRQHandler,   /* DMA1 Channel2 Global */
    DMA1_Channel3_IRQHandler,   /* DMA1 Channel3 Global */
    DMA1_Channel4_IRQHandler,   /* DMA1 Channel4 Global */
    DMA1_Channel5_IRQHandler,   /* DMA1 Channel5 Global */
    DMA1_Channel6_IRQHandler,   /* DMA1 Channel6 Global */
    DMA1_Channel7_IRQHandler,   /* DMA1 Channel7 Global */
    ADC1_2_IRQHandler,          /* ADC1 and ADC2 Global */
    USB_HP_CAN1_TX_IRQHandler,  /* USB High Priority or CAN TX */
    USB_LP_CAN1_RX0_IRQHandler, /* USB Low Priority or CAN RX0 */
    CAN1_RX1_IRQHandler,        /* CAN RX1 */
    CAN1_SCE_IRQHandler,        /* CAN SCE */
    EXTI9_5_IRQHandler,         /* EXTI Line[9:5] */
    TIM1_BRK_IRQHandler,        /* TIM1 Break */
    TIM1_UP_IRQHandler,         /* TIM1 Update */
    TIM1_TRG_COM_IRQHandler,    /* TIM1 Trigger and Commutation */
    TIM1_CC_IRQHandler,         /* TIM1 Capture Compare */
    TIM2_IRQHandler,            /* TIM2 Global */
    TIM3_IRQHandler,            /* TIM3 Global */
    TIM4_IRQHandler,            /* TIM4 Global */
    I2C1_EV_IRQHandler,         /* I2C1 Event */
    I2C1_ER_IRQHandler,         /* I2C1 Error */
    I2C2_EV_IRQHandler,         /* I2C2 Event */
    I2C2_ER_IRQHandler,         /* I2C2 Error */
    SPI1_IRQHandler,            /* SPI1 Global */
    SPI2_IRQHandler,            /* SPI2 Global */
    USART1_IRQHandler,          /* USART1 Global */
    USART2_IRQHandler,          /* USART2 Global */
    USART3_IRQHandler,          /* USART3 Global */
    EXTI15_10_IRQHandler,       /* EXTI Line[15:10] */
    RTCAlarm_IRQHandler,        /* RTC Alarm EXTI Line */
    USBWakeUp_IRQHandler,       /* USB WakeUp EXTI Line */
    TIM8_BRK_IRQHandler,        /* TIM8 Break */
    TIM8_UP_IRQHandler,         /* TIM8 Update */
    TIM8_TRG_COM_IRQHandler,    /* TIM8 Trigger and Commutation */
    TIM_CC_IRQHandler,          /* TIM8 Capture Compare */
    ADC3_IRQHandler,            /* ADC3 Global */
    FSMC_IRQHandler,            /* FSMC Global */
    SDIO_IRQHandler,            /* SDIO Global */
    TIM5_IRQHandler,            /* TIM5 Global */
    SPI3_IRQHandler,            /* SPI3 Global */
    UART4_IRQHandler,           /* UART4 Global */
    UART5_IRQHandler,           /* UART5 Global */
    TIM6_IRQHandler,            /* TIM6 Global */
    TIM7_IRQHandler,            /* TIM7 Global */
    DMA2_Channel1_IRQHandler,   /* DMA2 Channel1 global */
    DMA2_Channel2_IRQHandler,   /* DMA2 Channel2 global */
    DMA2_Channel3_IRQHandler,   /* DMA2 Channel3 global */
};

The linker script:

NTRY(Reset_Handler)

MEMORY
{
  RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
  FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
}


SECTIONS
{
    .text :
        {
            *(.isr_vector)
            *(.after_vectors)
            *(.text)
        } > FLASH

    .bss :
        {
            __bss_start__ = .;      /* symbol for c code to initialize bss section */
            *(.bss)
            *(COMMON)
            __bss_end__ = .;        /* symbol for c code to initialize bss section */
        } > RAM
}

It is built with:

/opt/gcc-arm-none-eabi-7-2017-q4-major/bin/arm-none-eabi-gcc -c -mcpu=cortex-m3 -mthumb -g main.c -o main.o
/opt/gcc-arm-none-eabi-7-2017-q4-major/bin/arm-none-eabi-ld -T main.ld -Map main.map --cref main.o -o main.elf

I condensed all the code into one file for ease of posting as a question.

Chris
  • 121
  • 1

0 Answers0