Hi Guys,
This is outside the typical maker space, and some may call me foolish for trying to do this, but learning the basics of STM32s without the ST abstractions, in my own time through the excellent series of guides by Vivonomicon. I’m currently learning interrupts, but my program seems to trigger a SIGTRAP fail when the interrupt fires.
The code consists of main.c for the main loop and setup code, and nvic.c for holding the ISRs. There are a few header files for the volatile led_on variable and pin constants, It’s running on an STM32413ZH Nucleo-144 board (I plan to use an 8080 LCD soon). All it does is watch the global led_on variable in the main loop, and on a rising edge on the on-board button (PC13) it’ll toggle this variable (or at least that’s what it’s supposed to do)
// main.c
#include "main.h"
int main(void){
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; // Enable GPIO bank B
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; // Enable GPIO bank C
GPIOB->MODER = 0x1; // set Pin 0 to output mode
// GPIOC is already in all input mode
GPIOB->OSPEEDR = 0x0;
GPIOB->PUPDR = 0x0;
GPIOB->OTYPER = 0x0;
// uint8_t button_down = 0;
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // Enable system configuration peripheral
SYSCFG->EXTICR[3] &= ~(SYSCFG_EXTICR4_EXTI13_Msk); // Turn off all bits in EXTICR4 for pin 13 in all GPIO registers
SYSCFG->EXTICR[3] |= (SYSCFG_EXTICR4_EXTI13_PC); // Turn on the relevant bits for bank C
EXTI->IMR |= (1 << BUTTON_PIN); // Enable button's EXTI line
EXTI->FTSR &= ~(1 << BUTTON_PIN); // Disable falling edge trigger (button release)
EXTI->RTSR |= (1 << BUTTON_PIN); // Enable rising edge trigger
NVIC_SetPriority(EXTI15_10_IRQn, 0x03);
NVIC_EnableIRQ(EXTI15_10_IRQn);
while (1) {
if (led_on) {
GPIOB->ODR |= (1 << LED_PIN);
}
else {
GPIOB->ODR &= ~(1 << LED_PIN);
}
}
}
// nvic.c
#include "nvic.h"
void EXTI15_10_IRQHandler(void){
if (EXTI->PR & (1 << BUTTON_PIN)) {
// Clear the EXTI status flag.
EXTI->PR |= (1 << BUTTON_PIN);
// Toggle the global 'led on?' variable.
led_on = !led_on;
}
}
void HardFault_Handler(void)
{
/* Go to infinite loop when Hard Fault exception occurs */
while (1)
{
}
}
This sequence is press button > sitgtrap pauses gdb > backtrace shows the above. Looks like it calls my ISR, but then there’s an unknown error handler in there afterwards?
If anyone is a wizard at these sorts of thing, or has some pointers for me to check, that’d be greatly appreciated! If there’s any part of my code you need explained, I’m sure I’d love the rubber duck experience I posted this on the ST forum, but they’ve been unresponsive so far. If there’s a better place for this question, I’m happy to be redirected.
Keen to get to the bottom of this one!
-James
Code .zip attached
interrupt problems.zip (194.0 KB)