Migration to STM32 Cores. Changes in Interrupts.
Posted: Sat Apr 25, 2020 1:48 pm
Recently i add from the board manager the STM32 Cores.
I used to work with low level programming and at this time i don't want to change it.
Using the STM32 Cores the code below is not working. It hang after a while, when it enter in the interrupt. I suppose i have to replace the interrupt vector "extern "C" void __irq_tim2()". I tried "void TIM2_IRQHandler()" with the same result.
What changes I need to make, in order for the following code to work?
Vasilis
I used to work with low level programming and at this time i don't want to change it.
Using the STM32 Cores the code below is not working. It hang after a while, when it enter in the interrupt. I suppose i have to replace the interrupt vector "extern "C" void __irq_tim2()". I tried "void TIM2_IRQHandler()" with the same result.
What changes I need to make, in order for the following code to work?
Code: Select all
//Toggling the onboard led on PC13 every 2 sec.
volatile boolean led = 1 ;
#define RCCAPB1ENR_ (*((volatile uint32_t *) (0x40021000+0x1C)))
#define RCCAPB2ENR_ (*((volatile uint32_t *) (0x40021000+0x18)))
#define GPIOLC (*((volatile uint32_t *) (0x40011000)))
#define GPIOHC (*((volatile uint32_t *) (0x40011000+0x04)))
#define ODR_C (*((volatile uint32_t *) (0x40011000+0x0C)))
#define BSRRC_ (*((volatile uint32_t *) (0x40011000+0x10)))
#define TIM2CR1 (*((volatile uint32_t *) (0x40000000)))
#define TIM2CR2 (*((volatile uint32_t *) (0x40000000+0x04)))
#define TIM2SMCR (*((volatile uint32_t *) (0x40000000+0x08)))
#define TIM2DIER (*((volatile uint32_t *) (0x40000000+0x0C)))
#define TIM2SR (*((volatile uint32_t *) (0x40000000+0x10)))
#define TIM2EGR (*((volatile uint32_t *) (0x40000000+0x14)))
#define TIM2CCMR1 (*((volatile uint32_t *) (0x40000000+0x18)))
#define TIM2CCMR2 (*((volatile uint32_t *) (0x40000000+0x1C)))
#define TIM2CCER (*((volatile uint32_t *) (0x40000000+0x20)))
#define TIM2CNT (*((volatile uint32_t *) (0x40000000+0x24)))
#define TIM2PSC (*((volatile uint32_t *) (0x40000000+0x28)))
#define TIM2ARR (*((volatile uint32_t *) (0x40000000+0x2C)))
#define TIM2CCR1 (*((volatile uint32_t *) (0x40000000+0x34)))
#define TIM2CCR2 (*((volatile uint32_t *) (0x40000000+0x38)))
#define TIM2CCR3 (*((volatile uint32_t *) (0x40000000+0x3C)))
#define TIM2CCR4 (*((volatile uint32_t *) (0x40000000+0x40)))
#define TIM2DCR (*((volatile uint32_t *) (0x40000000+0x48)))
#define TIM2DMAR (*((volatile uint32_t *) (0x40000000+0x4C)))
#define IPR8_ (*((volatile uint32_t *) (0xE000E100+0x308)))
#define ISER0_ (*((volatile uint32_t *) (0xE000E100)))
void setup()
{
Serial.begin(250000);
Serial.println("Start");
RCCAPB1ENR_ = RCCAPB1ENR_ | 0x001 ; // Enable Timer 2 RM p114
RCCAPB2ENR_ = RCCAPB2ENR_ | 0x10; // In order to make changes in GPIOC, Enable port row C. RM p112
GPIOHC = 0x44144444; // Set output mode on PC13
asm volatile("cpsie i"); // Enables interrupts and configurable fault handlers. p99 C
TIM2CR1 = 0;
TIM2CR2 = 0;
TIM2SMCR = 0;
TIM2DIER = 0;
TIM2SR = 0;
TIM2EGR = 0;
TIM2CCMR1 = 0;
TIM2CCMR2 = 0;
TIM2CCER = 0;
TIM2CNT = 0;
TIM2PSC = 0;
TIM2ARR = 65535; // Always FFFF
TIM2CCR1 = 0;
TIM2CCR2 = 0;
TIM2CCR3 = 0;
TIM2CCR4 = 0;
TIM2DCR = 0;
TIM2DMAR = 0;
//Update_event = TIM_CLK/((PSC + 1)*(ARR + 1)) = 72.000.000. / ((35999+1)*(1999+1))= 1Hz = 1 per Sec
TIM2PSC = 35999; // Set prescaler to 35999 (PSC + 1) Means 72.000.000 / 36000 = 2.000 counts per second p417
TIM2ARR = 1999; // Auto reload value 2000. p355
TIM2DIER = TIM2DIER | 0x1; // Interrupt when the counter overflow. TIM_DIER_UIE = 1. p408
TIM2CR1 = TIM2CR1 | 0x04; // TIM_CR1_URS = 1 Only counter overflow/underflow generates an update interrupt or DMA request if enabled. p403
IPR8_ = IPR8_ & 0x20FFFFFF; // Set highest priority 2. From the table TIM2 global interrupt = 35.p204 Reference Manual, Find the suitable IPR = 35 / 4,= 8 and the suitable byte 3
// 0 being highest priority and 15 being lowest p118 Programming Manual. Move it to the left 4 positions. p125 Programming Manual
ISER0_ = ISER0_ | 0x10000000; // Enable interrupt TIM2 global interrupt. From the table position TIM2 global interrupt = 28. p204 Reference Manual Position bit = 28 p120 Programming Manual.
TIM2SR = TIM2SR & 0xFFFFFFFE; // clear pending interrupt UIF flag TIM_SR_UIF=0. p409. Always before enable an interrupt we must clear any pending interrupts.
TIM2EGR = TIM2EGR| 0x0001; // Re-initialize the counter and generates an update of the registers.
TIM2CR1 = TIM2CR1 | 0x1; // CEN = 1 Enable timer. p337
}
void loop()
{
BSRRC_ = BSRRC_ |(1 << (13 + (led * 16))); // Toggle PC13. Lower 16 bits setting while higher bits clearing. p172
Serial.println(led); // Show me Led status
}
extern "C" void __irq_tim2() // https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/master/STM32F1/cores/maple/libmaple/stm32f1/performance/vector_table.S
//void TIM2_IRQHandler()
{
TIM2SR = TIM2SR & 0xFFFFFFFE; // Never try and clear the flag that caused the interrupt as the last instruction in the ISR itself. It causes the ISR to reenter immediately.
led = !led; // Reverse state
}