Using CMSIS NVIC functions to set custom timer interrupt handler.

Dependencies:   mbed

Committer:
Ladon
Date:
Fri Aug 02 04:25:43 2019 +0000
Revision:
4:c52637c8d084
Parent:
3:db424769ecca
Child:
5:3ee6e0113b41
Cleaned up code a bit..

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Ladon 3:db424769ecca 1 //#include <mbed.h>
Ladon 3:db424769ecca 2 #include "stm32f303xe.h"
Ladon 0:12efa8652054 3 #include <iostream>
Ladon 0:12efa8652054 4 #include <iomanip>
Ladon 0:12efa8652054 5
Ladon 0:12efa8652054 6 using namespace std;
Ladon 0:12efa8652054 7
Ladon 0:12efa8652054 8 // Timer functions:
Ladon 0:12efa8652054 9 // -
Ladon 0:12efa8652054 10
Ladon 4:c52637c8d084 11 void inline timer_enable ()
Ladon 0:12efa8652054 12 {
Ladon 4:c52637c8d084 13 TIM2->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
Ladon 0:12efa8652054 14 }
Ladon 0:12efa8652054 15
Ladon 4:c52637c8d084 16 void inline timer_enable_interrupt ()
Ladon 0:12efa8652054 17 {
Ladon 2:7c45a714b991 18 TIM2->DIER = TIM_DIER_UIE;
Ladon 0:12efa8652054 19 }
Ladon 0:12efa8652054 20
Ladon 4:c52637c8d084 21 void inline timer_clear_status ()
Ladon 0:12efa8652054 22 {
Ladon 2:7c45a714b991 23 TIM2->SR = 0;
Ladon 0:12efa8652054 24 }
Ladon 0:12efa8652054 25
Ladon 4:c52637c8d084 26 void inline timer_downscale_by (const unsigned short& v)
Ladon 0:12efa8652054 27 {
Ladon 2:7c45a714b991 28 cout << "Downscaling counter by : 0x" << hex << 1 + v << endl;
Ladon 2:7c45a714b991 29 TIM2->PSC = v;
Ladon 0:12efa8652054 30 }
Ladon 0:12efa8652054 31
Ladon 4:c52637c8d084 32 void inline timer_downscale_by_max ()
Ladon 0:12efa8652054 33 {
Ladon 4:c52637c8d084 34 timer_downscale_by(0xFFFF);
Ladon 0:12efa8652054 35 }
Ladon 0:12efa8652054 36
Ladon 4:c52637c8d084 37 void inline timer_limit_counter_to (const unsigned int& v)
Ladon 0:12efa8652054 38 {
Ladon 2:7c45a714b991 39 cout << "Limiting counter to : 0x" << hex << v << endl;
Ladon 2:7c45a714b991 40 TIM2->ARR = v;
Ladon 0:12efa8652054 41 }
Ladon 0:12efa8652054 42
Ladon 4:c52637c8d084 43 void inline timer_set_interrupt_period_to (const double& T)
Ladon 0:12efa8652054 44 {
Ladon 4:c52637c8d084 45 timer_limit_counter_to(36000);
Ladon 4:c52637c8d084 46 timer_downscale_by(1999 + (T - 1) * 2e3);
Ladon 1:8d34cf217c0a 47 // ^This allows : 500us <= T <= 32.768
Ladon 1:8d34cf217c0a 48 // The ^former was found by solving : 0 <= 1999 + (T - 1) * 2e3 <= 0xFFFF, for the prescaler register.
Ladon 1:8d34cf217c0a 49 // -
Ladon 0:12efa8652054 50 }
Ladon 0:12efa8652054 51
Ladon 0:12efa8652054 52 // GPIOA functions:
Ladon 0:12efa8652054 53 // -
Ladon 0:12efa8652054 54
Ladon 4:c52637c8d084 55 void led_init ()
Ladon 0:12efa8652054 56 {
Ladon 2:7c45a714b991 57 GPIOA->MODER &= ~GPIO_MODER_MODER5;
Ladon 2:7c45a714b991 58 // Set as output.
Ladon 0:12efa8652054 59 // -
Ladon 2:7c45a714b991 60 GPIOA->MODER |= 1 << GPIO_MODER_MODER5_Pos;
Ladon 0:12efa8652054 61 }
Ladon 0:12efa8652054 62
Ladon 4:c52637c8d084 63 void led_toggle ()
Ladon 0:12efa8652054 64 {
Ladon 2:7c45a714b991 65 GPIOA->ODR ^= GPIO_ODR_5;
Ladon 0:12efa8652054 66 }
Ladon 0:12efa8652054 67
Ladon 0:12efa8652054 68 // Other functions:
Ladon 0:12efa8652054 69 // -
Ladon 0:12efa8652054 70
Ladon 4:c52637c8d084 71 void inline clock_enable_for_timer ()
Ladon 0:12efa8652054 72 {
Ladon 2:7c45a714b991 73 RCC->APB1RSTR |= RCC_APB1RSTR_TIM2RST;
Ladon 2:7c45a714b991 74 RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM2RST;
Ladon 2:7c45a714b991 75 RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
Ladon 0:12efa8652054 76 }
Ladon 0:12efa8652054 77
Ladon 0:12efa8652054 78 // NVIC functions:
Ladon 0:12efa8652054 79 // -
Ladon 4:c52637c8d084 80 /*
Ladon 4:c52637c8d084 81 // I couldn 't get TIM2_IRQHandler() to work; probably wrong name.
Ladon 4:c52637c8d084 82 // -
Ladon 2:7c45a714b991 83 extern "C" void TIM2_IRQHandler (void)
Ladon 0:12efa8652054 84 {
Ladon 2:7c45a714b991 85 cout << "Interrupt hit!" << endl;
Ladon 2:7c45a714b991 86 clear_timer_status();
Ladon 0:12efa8652054 87 toggle_LED();
Ladon 0:12efa8652054 88 }
Ladon 4:c52637c8d084 89 */
Ladon 4:c52637c8d084 90 void interrupt_handler ()
Ladon 3:db424769ecca 91 {
Ladon 3:db424769ecca 92 cout << "Interrupt hit!" << endl;
Ladon 4:c52637c8d084 93 timer_clear_status();
Ladon 4:c52637c8d084 94 led_toggle();
Ladon 3:db424769ecca 95 }
Ladon 3:db424769ecca 96
Ladon 4:c52637c8d084 97 inline void interrupt_enable ()
Ladon 0:12efa8652054 98 {
Ladon 4:c52637c8d084 99 // NVIC_SetPriority(TIM2_IRQn, 250);
Ladon 2:7c45a714b991 100 NVIC_EnableIRQ(TIM2_IRQn);
Ladon 4:c52637c8d084 101 NVIC_SetVector(TIM2_IRQn, (uint32_t) &interrupt_handler);
Ladon 0:12efa8652054 102 }
Ladon 0:12efa8652054 103
Ladon 0:12efa8652054 104 //
Ladon 0:12efa8652054 105 // -
Ladon 0:12efa8652054 106 //
Ladon 0:12efa8652054 107
Ladon 0:12efa8652054 108 int main ()
Ladon 0:12efa8652054 109 {
Ladon 0:12efa8652054 110 cout << "Entered main()." << endl;
Ladon 4:c52637c8d084 111 led_init();
Ladon 4:c52637c8d084 112 clock_enable_for_timer();
Ladon 2:7c45a714b991 113 TIM2->ARR = 0xffffffff;
Ladon 2:7c45a714b991 114 TIM2->CR1 = TIM2->CR2 = TIM2->SMCR = TIM2->DIER = TIM2->SR = TIM2->CCMR1 = TIM2->CCMR2
Ladon 2:7c45a714b991 115 = TIM2->CCER = TIM2->CNT = TIM2->PSC = TIM2->CCR1 = TIM2->CCR2 = TIM2->CCR3
Ladon 2:7c45a714b991 116 = TIM2->CCR4 = TIM2->DCR = TIM2->DMAR = 0;
Ladon 3:db424769ecca 117 TIM2->CR1 |= TIM_CR1_UDIS;
Ladon 4:c52637c8d084 118 timer_downscale_by_max();
Ladon 4:c52637c8d084 119 timer_limit_counter_to(0x1000);
Ladon 0:12efa8652054 120 // ^ LED stays open for 0.5 and closed for 0.5 with a total of 1 sec.
Ladon 0:12efa8652054 121 // -
Ladon 4:c52637c8d084 122 timer_clear_status();
Ladon 4:c52637c8d084 123 timer_enable_interrupt();
Ladon 4:c52637c8d084 124 timer_enable();
Ladon 4:c52637c8d084 125 interrupt_enable();
Ladon 0:12efa8652054 126 cout << "Exiting main().." << endl;
Ladon 0:12efa8652054 127 cout << endl;
Ladon 3:db424769ecca 128 cout << hex
Ladon 3:db424769ecca 129 << "Status : 0x" << TIM2->SR << endl
Ladon 3:db424769ecca 130 << "Count : 0x" << TIM2->CNT << endl;
Ladon 3:db424769ecca 131 TIM2->CR1 &= ~TIM_CR1_UDIS;
Ladon 2:7c45a714b991 132 while (true)
Ladon 2:7c45a714b991 133 {
Ladon 2:7c45a714b991 134 cout << hex
Ladon 2:7c45a714b991 135 << "Status : 0x" << TIM2->SR << endl
Ladon 2:7c45a714b991 136 << "Count : 0x" << TIM2->CNT << endl;
Ladon 3:db424769ecca 137 if (TIM2->CNT > 2)
Ladon 3:db424769ecca 138 TIM2->SR = 0;
Ladon 2:7c45a714b991 139 }
Ladon 0:12efa8652054 140 }