Controlling PWM of LED through direct access of TIM2 timer's registers.

Dependencies:   mbed

Revision:
8:6464500cc838
Parent:
7:d93dcab712f1
Child:
9:e65dd1ad537e
--- a/main.cpp	Fri Aug 02 06:03:16 2019 +0000
+++ b/main.cpp	Fri Aug 02 12:18:17 2019 +0000
@@ -11,8 +11,30 @@
     // -
     // Port Mode Register.
     // -
+//    GPIOA->MODER &= ~GPIO_MODER_MODER5;
+//    GPIOA->MODER |= 1 << GPIO_MODER_MODER5_Pos;
+    // Set PA5 as AF1.
+    // -
+///*
+    GPIOA->AFR[0] &= ~GPIO_AFRL_AFRL5;
+    GPIOA->AFR[0] |= 1 << GPIO_AFRL_AFRL5_Pos;
+    GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5;
     GPIOA->MODER &= ~GPIO_MODER_MODER5;
-    GPIOA->MODER |= 1 << GPIO_MODER_MODER5_Pos;
+    GPIOA->MODER |= 2 << GPIO_MODER_MODER5_Pos;
+    cout << "AFR    : 0x" << hex << (GPIOA->AFR[0] & GPIO_AFRL_AFRL5) << endl;
+    cout << "OSPEED : 0x" << (GPIOA->OSPEEDR & GPIO_OSPEEDER_OSPEEDR5) << endl;
+    cout << "MODER  : 0x" << (GPIOA->MODER & GPIO_MODER_MODER5) << endl;
+//*/
+/*
+    GPIOA->AFR[0] &= ~GPIO_AFRL_AFRL0;
+    GPIOA->AFR[0] |= 1 << GPIO_AFRL_AFRL0_Pos;
+    GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0;
+    GPIOA->MODER &= ~GPIO_MODER_MODER0;
+    GPIOA->MODER |= 2 << GPIO_MODER_MODER0_Pos;
+    cout << "AFR    : 0x" << hex << (GPIOA->AFR[0] & GPIO_AFRL_AFRL0) << endl;
+    cout << "OSPEED : 0x" << (GPIOA->OSPEEDR & GPIO_OSPEEDER_OSPEEDR0) << endl;
+    cout << "MODER  : 0x" << (GPIOA->MODER & GPIO_MODER_MODER0) << endl;
+*/
 }
 
 void inline reset_timer ()
@@ -32,6 +54,16 @@
     RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
 }
 
+void inline timer_enable_pwm ()
+{
+    TIM2->CCR1 = TIM2->ARR * 0.9;
+//    TIM2->CCMR1 = (0b111 << TIM_CCMR1_OC1M_Pos) | TIM_CCMR1_OC1PE | TIM_CCMR1_OC1FE;
+    TIM2->CCMR1 = (0b111 << TIM_CCMR1_OC1M_Pos) | TIM_CCMR1_OC1FE;
+    TIM2->CCER &= ~TIM_CCER_CC1NP;
+    TIM2->CCER |= TIM_CCER_CC1E;
+    cout << "CCMR1 : 0x" << hex << TIM2->CCMR1 << endl;
+}
+
 void inline timer_downscale_by (const unsigned short& v)
 {
     // Prescaler.
@@ -48,11 +80,9 @@
 
 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.
+    // Precondition : T <= 59.
     // -
-    timer_limit_counter_to(36000);
-    timer_downscale_by(1999 + (T - 1) * 2e3);
+    timer_limit_counter_to(72000000 * T);
 }
 
 void inline timer_enable_interrupt ()
@@ -60,7 +90,8 @@
     // DMA/ Interrupt Enable Register.
     //     Update Interrupt Enable.
     // -
-    TIM2->DIER = TIM_DIER_UIE;
+//    TIM2->DIER = TIM_DIER_UIE | TIM_DIER_CC1IE;
+    TIM2->DIER |= TIM_DIER_UIE;
 }
 
 void inline timer_enable ()
@@ -68,7 +99,10 @@
     // Control Register 1.
     //     Update Request Source | Counter Enable.
     // -
-    TIM2->CR1 = TIM_CR1_URS | TIM_CR1_CEN;
+//    TIM2->CR1 = TIM_CR1_ARPE | TIM_CR1_URS;
+    TIM2->CR1 = TIM_CR1_URS;
+//    TIM2->EGR |= TIM_EGR_UG;
+    TIM2->CR1 |= TIM_CR1_CEN;
 }
 
 void inline timer_clear_status ()
@@ -101,9 +135,9 @@
 // -
 void interrupt_handler ()
 {
-    cout << "Interrupt hit!" << endl;
+//    cout << "SR : 0x" << hex << TIM2->SR << endl;
     timer_clear_status();
-    led_toggle();
+//    led_toggle();
 }
 
 inline void interrupt_enable ()
@@ -124,17 +158,10 @@
     cout << "Entered main()." << endl;
     led_init();
     clock_enable_for_timer();
-    timer_set_period_to(1.3);
+    timer_set_period_to(0.1);
     timer_enable_interrupt();
+    timer_enable_pwm();
     timer_enable();
     interrupt_enable();
-    /*
-        while (true)
-        {
-            cout << hex
-                 << "Status : 0x" << TIM2->SR << endl
-                 << "Count  : 0x" << TIM2->CNT << endl;
-        }
-    */
     cout << "Exiting main().." << endl;
 }
\ No newline at end of file