Using CMSIS NVIC functions to set custom timer interrupt handler.

Dependencies:   mbed

Committer:
Ladon
Date:
Fri Aug 02 04:16:14 2019 +0000
Revision:
3:db424769ecca
Parent:
2:7c45a714b991
Child:
4:c52637c8d084
First working version, i think..

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 2:7c45a714b991 11 void inline enable_timer ()
Ladon 0:12efa8652054 12 {
Ladon 3:db424769ecca 13 TIM2->CR1 |= TIM_CR1_ARPE | TIM_CR1_OPM | TIM_CR1_URS | TIM_CR1_CEN;
Ladon 0:12efa8652054 14 }
Ladon 0:12efa8652054 15
Ladon 2:7c45a714b991 16 void inline enable_timer_interrupt ()
Ladon 0:12efa8652054 17 {
Ladon 2:7c45a714b991 18 cout << "Setting DIER..." << endl;
Ladon 2:7c45a714b991 19 cout << "DIER was : 0x" << hex << TIM2->DIER << endl;
Ladon 2:7c45a714b991 20 cout << "Status is : 0x" << hex << TIM2->SR << endl;
Ladon 2:7c45a714b991 21 TIM2->DIER = TIM_DIER_UIE;
Ladon 2:7c45a714b991 22 cout << "Set DIER." << endl;
Ladon 0:12efa8652054 23 }
Ladon 0:12efa8652054 24
Ladon 2:7c45a714b991 25 void inline clear_timer_status ()
Ladon 0:12efa8652054 26 {
Ladon 2:7c45a714b991 27 TIM2->SR = 0;
Ladon 0:12efa8652054 28 }
Ladon 0:12efa8652054 29
Ladon 2:7c45a714b991 30 void inline reset_timer ()
Ladon 0:12efa8652054 31 {
Ladon 2:7c45a714b991 32 TIM2->EGR = TIM_EGR_UG;
Ladon 2:7c45a714b991 33 clear_timer_status();
Ladon 0:12efa8652054 34 }
Ladon 0:12efa8652054 35
Ladon 2:7c45a714b991 36 void inline downscale_timer_by (const unsigned short& v)
Ladon 0:12efa8652054 37 {
Ladon 2:7c45a714b991 38 cout << "Downscaling counter by : 0x" << hex << 1 + v << endl;
Ladon 2:7c45a714b991 39 TIM2->PSC = v;
Ladon 0:12efa8652054 40 }
Ladon 0:12efa8652054 41
Ladon 2:7c45a714b991 42 void inline downscale_timer_max ()
Ladon 0:12efa8652054 43 {
Ladon 2:7c45a714b991 44 downscale_timer_by(0xFFFF);
Ladon 0:12efa8652054 45 }
Ladon 0:12efa8652054 46
Ladon 2:7c45a714b991 47 void inline limit_timer_counter_to (const unsigned int& v)
Ladon 0:12efa8652054 48 {
Ladon 2:7c45a714b991 49 cout << "Limiting counter to : 0x" << hex << v << endl;
Ladon 2:7c45a714b991 50 TIM2->ARR = v;
Ladon 0:12efa8652054 51 }
Ladon 0:12efa8652054 52
Ladon 0:12efa8652054 53 void inline set_interrupt_period_to (const double& T)
Ladon 0:12efa8652054 54 {
Ladon 2:7c45a714b991 55 limit_timer_counter_to(36000);
Ladon 2:7c45a714b991 56 downscale_timer_by(1999 + (T - 1) * 2e3);
Ladon 1:8d34cf217c0a 57 // ^This allows : 500us <= T <= 32.768
Ladon 1:8d34cf217c0a 58 // The ^former was found by solving : 0 <= 1999 + (T - 1) * 2e3 <= 0xFFFF, for the prescaler register.
Ladon 1:8d34cf217c0a 59 // -
Ladon 0:12efa8652054 60 }
Ladon 0:12efa8652054 61
Ladon 0:12efa8652054 62 void inline set_interrupt_period_to_1sec ()
Ladon 0:12efa8652054 63 {
Ladon 0:12efa8652054 64 set_interrupt_period_to(1);
Ladon 0:12efa8652054 65 }
Ladon 0:12efa8652054 66
Ladon 0:12efa8652054 67 // GPIOA functions:
Ladon 0:12efa8652054 68 // -
Ladon 0:12efa8652054 69
Ladon 0:12efa8652054 70 void init_LED ()
Ladon 0:12efa8652054 71 {
Ladon 2:7c45a714b991 72 GPIOA->MODER &= ~GPIO_MODER_MODER5;
Ladon 2:7c45a714b991 73 // Set as output.
Ladon 0:12efa8652054 74 // -
Ladon 2:7c45a714b991 75 GPIOA->MODER |= 1 << GPIO_MODER_MODER5_Pos;
Ladon 0:12efa8652054 76 }
Ladon 0:12efa8652054 77
Ladon 0:12efa8652054 78 void toggle_LED ()
Ladon 0:12efa8652054 79 {
Ladon 2:7c45a714b991 80 GPIOA->ODR ^= GPIO_ODR_5;
Ladon 0:12efa8652054 81 }
Ladon 0:12efa8652054 82
Ladon 0:12efa8652054 83 // Other functions:
Ladon 0:12efa8652054 84 // -
Ladon 0:12efa8652054 85
Ladon 2:7c45a714b991 86 void inline enable_clock_for_timer ()
Ladon 0:12efa8652054 87 {
Ladon 2:7c45a714b991 88 RCC->APB1RSTR |= RCC_APB1RSTR_TIM2RST;
Ladon 2:7c45a714b991 89 RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM2RST;
Ladon 2:7c45a714b991 90 RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
Ladon 0:12efa8652054 91 }
Ladon 0:12efa8652054 92
Ladon 0:12efa8652054 93 // NVIC functions:
Ladon 0:12efa8652054 94 // -
Ladon 0:12efa8652054 95
Ladon 2:7c45a714b991 96 extern "C" void TIM2_IRQHandler (void)
Ladon 0:12efa8652054 97 {
Ladon 2:7c45a714b991 98 cout << "Interrupt hit!" << endl;
Ladon 2:7c45a714b991 99 clear_timer_status();
Ladon 0:12efa8652054 100 toggle_LED();
Ladon 0:12efa8652054 101 }
Ladon 0:12efa8652054 102
Ladon 3:db424769ecca 103 void fun ()
Ladon 3:db424769ecca 104 {
Ladon 3:db424769ecca 105 cout << "Interrupt hit!" << endl;
Ladon 3:db424769ecca 106 clear_timer_status();
Ladon 3:db424769ecca 107 toggle_LED();
Ladon 3:db424769ecca 108 }
Ladon 3:db424769ecca 109
Ladon 0:12efa8652054 110 inline void enable_interrupt ()
Ladon 0:12efa8652054 111 {
Ladon 3:db424769ecca 112 NVIC_SetPriority(TIM2_IRQn, 250);
Ladon 3:db424769ecca 113 cout << "TIM2_IRQn priority : " << NVIC_GetPriority(TIM2_IRQn) << endl;
Ladon 2:7c45a714b991 114 NVIC_EnableIRQ(TIM2_IRQn);
Ladon 3:db424769ecca 115 cout << "TIM2_IRQn status : " << NVIC_GetEnableIRQ(TIM2_IRQn) << endl;
Ladon 3:db424769ecca 116 cout << "TIM2_IRQn pending : " << NVIC_GetPendingIRQ(TIM2_IRQn) << endl;
Ladon 3:db424769ecca 117 NVIC_SetVector(TIM2_IRQn, (uint32_t) &fun);
Ladon 0:12efa8652054 118 }
Ladon 0:12efa8652054 119
Ladon 0:12efa8652054 120 //
Ladon 0:12efa8652054 121 // -
Ladon 0:12efa8652054 122 //
Ladon 0:12efa8652054 123
Ladon 0:12efa8652054 124 int main ()
Ladon 0:12efa8652054 125 {
Ladon 0:12efa8652054 126 cout << "Entered main()." << endl;
Ladon 0:12efa8652054 127 init_LED();
Ladon 2:7c45a714b991 128 enable_clock_for_timer();
Ladon 2:7c45a714b991 129 TIM2->ARR = 0xffffffff;
Ladon 2:7c45a714b991 130 TIM2->CR1 = TIM2->CR2 = TIM2->SMCR = TIM2->DIER = TIM2->SR = TIM2->CCMR1 = TIM2->CCMR2
Ladon 2:7c45a714b991 131 = TIM2->CCER = TIM2->CNT = TIM2->PSC = TIM2->CCR1 = TIM2->CCR2 = TIM2->CCR3
Ladon 2:7c45a714b991 132 = TIM2->CCR4 = TIM2->DCR = TIM2->DMAR = 0;
Ladon 3:db424769ecca 133 TIM2->CR1 |= TIM_CR1_UDIS;
Ladon 2:7c45a714b991 134 downscale_timer_max();
Ladon 2:7c45a714b991 135 limit_timer_counter_to(0x1000);
Ladon 0:12efa8652054 136 // ^ LED stays open for 0.5 and closed for 0.5 with a total of 1 sec.
Ladon 0:12efa8652054 137 // -
Ladon 2:7c45a714b991 138 clear_timer_status();
Ladon 3:db424769ecca 139 enable_timer_interrupt();
Ladon 2:7c45a714b991 140 enable_timer();
Ladon 2:7c45a714b991 141 enable_interrupt();
Ladon 0:12efa8652054 142 cout << "Exiting main().." << endl;
Ladon 0:12efa8652054 143 cout << endl;
Ladon 3:db424769ecca 144 cout << hex
Ladon 3:db424769ecca 145 << "Status : 0x" << TIM2->SR << endl
Ladon 3:db424769ecca 146 << "Count : 0x" << TIM2->CNT << endl;
Ladon 3:db424769ecca 147 TIM2->CR1 &= ~TIM_CR1_UDIS;
Ladon 2:7c45a714b991 148 while (true)
Ladon 2:7c45a714b991 149 {
Ladon 2:7c45a714b991 150 cout << hex
Ladon 2:7c45a714b991 151 << "Status : 0x" << TIM2->SR << endl
Ladon 2:7c45a714b991 152 << "Count : 0x" << TIM2->CNT << endl;
Ladon 3:db424769ecca 153 if (TIM2->CNT > 2)
Ladon 3:db424769ecca 154 TIM2->SR = 0;
Ladon 2:7c45a714b991 155 }
Ladon 0:12efa8652054 156 }