Using CMSIS NVIC functions to set custom timer interrupt handler.

Dependencies:   mbed

Revision:
5:3ee6e0113b41
Parent:
4:c52637c8d084
Child:
6:be045fed855f
diff -r c52637c8d084 -r 3ee6e0113b41 main.cpp
--- a/main.cpp	Fri Aug 02 04:25:43 2019 +0000
+++ b/main.cpp	Fri Aug 02 05:19:08 2019 +0000
@@ -1,92 +1,104 @@
-//#include <mbed.h>
-#include "stm32f303xe.h"
+#include <mbed.h>
 #include <iostream>
-#include <iomanip>
 
 using namespace std;
 
-// Timer functions:
-// -
-
-void inline timer_enable ()
+void led_init ()
 {
-    TIM2->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
+    // Led is at PA5.
+    // -
+    // Set PA5 as output.
+    // -
+    // Port Mode Register.
+    // -
+    GPIOA->MODER &= ~GPIO_MODER_MODER5;
+    GPIOA->MODER |= 1 << GPIO_MODER_MODER5_Pos;
 }
 
-void inline timer_enable_interrupt ()
+void inline reset_timer ()
 {
-    TIM2->DIER = TIM_DIER_UIE;
+    // Peripheral Reset Register.
+    // -
+    RCC->APB1RSTR |= RCC_APB1RSTR_TIM2RST;
+    RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM2RST;
 }
 
-void inline timer_clear_status ()
+void inline clock_enable_for_timer ()
 {
-    TIM2->SR = 0;
+    // Peripheral Clock Enable Register.
+    //     TIM2 Timer Clock Enable.
+    // -
+    reset_timer();
+    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
 }
 
 void inline timer_downscale_by (const unsigned short& v)
 {
-    cout << "Downscaling counter by : 0x" << hex << 1 + v << endl;
+    // Prescaler.
+    // -
     TIM2->PSC = v;
 }
 
-void inline timer_downscale_by_max ()
-{
-    timer_downscale_by(0xFFFF);
-}
-
 void inline timer_limit_counter_to (const unsigned int& v)
 {
-    cout << "Limiting counter to : 0x" << hex << v << endl;
+    // Auto-Reload Register.
+    // -
     TIM2->ARR = v;
 }
 
-void inline timer_set_interrupt_period_to (const double& T)
+void inline timer_set_period_to (const double& T)
 {
+    // This function allows : 500us <= T <= 32.768
+    //      The ^former was found by solving : 0 <= 1999 + (T - 1) * 2e3 <= 0xFFFF, for the prescaler register.
+    // -
     timer_limit_counter_to(36000);
     timer_downscale_by(1999 + (T - 1) * 2e3);
-    // ^This allows : 500us <= T <= 32.768
-    //      The ^former was found by solving : 0 <= 1999 + (T - 1) * 2e3 <= 0xFFFF, for the prescaler register.
-    // -
 }
 
-// GPIOA functions:
-// -
+void inline timer_enable_interrupt ()
+{
+    // DMA/ Interrupt Enable Register.
+    //     Update Interrupt Enable.
+    // -
+    TIM2->DIER = TIM_DIER_UIE;
+}
 
-void led_init ()
+void inline timer_enable ()
 {
-    GPIOA->MODER &= ~GPIO_MODER_MODER5;
-    // Set as output.
+    // Control Register 1.
+    //     Update Request Source | Counter Enable.
     // -
-    GPIOA->MODER |= 1 << GPIO_MODER_MODER5_Pos;
+    TIM2->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
+}
+
+void inline timer_clear_status ()
+{
+    // Status Register.
+    // -
+    TIM2->SR = 0;
 }
 
 void led_toggle ()
 {
+    // Output Data Register.
+    // -
     GPIOA->ODR ^= GPIO_ODR_5;
 }
 
-// Other functions:
-// -
-
-void inline clock_enable_for_timer ()
-{
-    RCC->APB1RSTR |= RCC_APB1RSTR_TIM2RST;
-    RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM2RST;
-    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
-}
+/* 
+    // I was unable to use the following handler :
+    // -
+    extern "C" void TIM2_IRQHandler (void)
+    {
+        cout << "Interrupt hit!" << endl;
+        clear_timer_status();
+        toggle_LED();
+    }
+*/
 
-// NVIC functions:
-// -
-/* 
-// I couldn 't get TIM2_IRQHandler() to work; probably wrong name.
+// I couldn 't get TIM2_IRQHandler() to work; probably wrong name. Thus, I 'll use a custom handler
+// and attach it using SetVector() from CMSIS : https://arm-software.github.io/CMSIS_5/Core/html/group__NVIC__gr.html.
 // -
-extern "C" void TIM2_IRQHandler (void)
-{
-    cout << "Interrupt hit!" << endl;
-    clear_timer_status();
-    toggle_LED();
-}
-*/
 void interrupt_handler ()
 {
     cout << "Interrupt hit!" << endl;
@@ -98,7 +110,9 @@
 {
 //    NVIC_SetPriority(TIM2_IRQn, 250);
     NVIC_EnableIRQ(TIM2_IRQn);
-    NVIC_SetVector(TIM2_IRQn, (uint32_t) &interrupt_handler);
+    NVIC_SetVector(TIM2_IRQn, (uint32_t) interrupt_handler);
+    // ^Definition of NVIC_SetVector() : https://arm-software.github.io/CMSIS_5/Core/html/group__NVIC__gr.html#gab43c1c59d5c081f1bc725237f4b1f916.
+    // -
 }
 
 //
@@ -110,31 +124,17 @@
     cout << "Entered main()." << endl;
     led_init();
     clock_enable_for_timer();
-    TIM2->ARR = 0xffffffff;
-    TIM2->CR1 = TIM2->CR2 = TIM2->SMCR = TIM2->DIER = TIM2->SR = TIM2->CCMR1 = TIM2->CCMR2
-              = TIM2->CCER = TIM2->CNT = TIM2->PSC = TIM2->CCR1 = TIM2->CCR2 = TIM2->CCR3 
-              = TIM2->CCR4 = TIM2->DCR = TIM2->DMAR = 0;
-    TIM2->CR1 |= TIM_CR1_UDIS;
-    timer_downscale_by_max();
-    timer_limit_counter_to(0x1000);
-    // ^ LED stays open for 0.5 and closed for 0.5 with a total of 1 sec.
-    // -
-    timer_clear_status();
+    timer_set_period_to(1.3);
     timer_enable_interrupt();
     timer_enable();
     interrupt_enable();
+    /*
+        while (true)
+        {
+            cout << hex
+                 << "Status : 0x" << TIM2->SR << endl
+                 << "Count  : 0x" << TIM2->CNT << endl;
+        }
+    */
     cout << "Exiting main().." << endl;
-    cout << endl;
-        cout << hex
-             << "Status : 0x" << TIM2->SR << endl
-             << "Count  : 0x" << TIM2->CNT << endl;
-    TIM2->CR1 &= ~TIM_CR1_UDIS;
-    while (true)
-    {
-        cout << hex
-             << "Status : 0x" << TIM2->SR << endl
-             << "Count  : 0x" << TIM2->CNT << endl;
-        if (TIM2->CNT > 2)
-            TIM2->SR = 0;
-    }
 }
\ No newline at end of file