I'm attempting to write an interrupt to keep basic time measured in ticks on an STM32F407VGT (Discovery Board.)
My interrupt appears to run once (though I cannot be sure), but it then crashes/locks up the processor completely. All UART output stops…
The code is essentially the same as in "The Definitive Guide to the ARM Cortex-M3, 2nd ed." (Joseph Yiu, Newnes.) Could the fact that the STM32F4xx is an ARM Cortex-M4 be a problem? If so, how do I fix this? I initially tried using TMR2, with similar issues, which makes me think it's something I'm missing. I've also tried using SysTickConfig, with the same problems.
uint32_t ticks;
void SysTickAlarm(void)
{
SysTick->CTRL = 0;
SCB->ICSR = SCB->ICSR & 0xFDFFFFFF;
ticks++;
return;
}
/*
* Initialise system timer
*/
void tick_init(void)
{
ticks = 0;
*((volatile unsigned int*)(SCB->VTOR + (15 << 2))) = (unsigned int) SysTickAlarm;
SysTick->CTRL = 0; // Disable SysTick
SysTick->LOAD = TICK_DELAY; // Delay for 10 ms
SysTick->VAL = 0; // Clear current value to 0
SysTick->CTRL = 0x7; // Enable SysTick+exception and use processor clock
}
/*
* get_ticks: Get the number of ticks since processor initialisation.
*/
uint32_t get_ticks()
{
return ticks;
}
main() calls tick_init() then starts spitting out printf("ticks=%d\n", get_ticks());
in a loop. But it stops fairly quickly, I get around 10 lines before it crashes.
I'm very new to ARM processors, so it's probably something very simple, but I can't see it.
Best Answer
You have created quite a problem for yourself by ditching the standard peripherals library (SPL). This microcontroller is hard enough to learn with it, let alone without. The library may be horribly designed but it has an advantage of actually working. I suggest you first get a simple test program working using SPL, then gradually reimplement its functionality if you really can't use it (I'm yet to see a technical reason for that however).
In order to use an interrupt in a Cortex-M3/M4, you need the following:
SCB->VTOR
register. By default it's 0, which (again by default) is the start of flash. If your startup code / linker script combination sets up the vector table correctly, great. The SPL does that. You don't seem to (unless it's in the code you didn't post). Look how it's done in the standard peripherals library (startup_stm32f4xx.s
and corresponding linker script for a gcc-based toolchain).NVIC->ISER[x]
andNVIC->IPR[x]
registers. See implementation ofNVIC_Init()
in the SPL and PM00214 section 4.3.If after checking all that you still can't get it to work, posting a complete (but minimal) project to analyze would be best.