Mark Gottscho / HardwareTimersLib

Fork of HardwareTimersLib by Mark Gottscho

Revision:
7:78f6ee57d324
Parent:
3:dd54446143ee
Child:
8:23c04123395c
--- a/Timer_PIT.cpp	Mon Mar 10 20:35:21 2014 +0000
+++ b/Timer_PIT.cpp	Tue Mar 11 00:52:13 2014 +0000
@@ -8,47 +8,77 @@
 #include "HardwareTimer.h"
 #include "Timer_PIT.h"
 
-//Init class static variable
-bool Timer_PIT::__initialized_pit = false;
-uint32_t Timer_PIT::__rolloverValue = 0xFFFFFFFF;
-uint32_t Timer_PIT::__count = 0;
+
+//Init Timer_PIT class variables
+bool Timer_PIT::__pit_used = false;
+Timer_PIT *Timer_PIT::__obj = NULL;
 
-
-Timer_PIT::Timer_PIT(float tickValue) :
-        HardwareTimer(tickValue)
+Timer_PIT::Timer_PIT() :
+        HardwareTimer(0xFFFFFFFF, 41.666666666, HardwareTimer::ns) //PIT has 32-bit counter. And at 24 MHz, each clock cycle is 41.666666 ns
         {   
+    if (__pit_used)
+        __valid = false;
+    else {
+        __valid = true;
+        __pit_used = true;
+        __obj = this;
+    }
 }
 
-Timer_PIT::~Timer_PIT() {}
-
-void Timer_PIT::disableTimer() {
-    if (!__valid)
-        return;
-        
-    PIT->MCR |= PIT_MCR_MDIS_MASK; //Setting MDIS bit disables the timer.
-    __enabled = false;
+Timer_PIT::~Timer_PIT() {
+    if (__valid) {
+        __pit_used = false; //free the hardware PIT resource
+        __obj = NULL;
+    }
 }
 
 uint32_t Timer_PIT::getTick() {
     if (!__valid)
         return 0;
         
-    //Get raw time
-    __disable_irq();
-    uint32_t tick = PIT->CHANNEL[0].CVAL;
+    NVIC_DisableIRQ(PIT_IRQn); //CRITICAL SECTION
+    uint32_t tick = PIT->CHANNEL[0].CVAL; //counts down
     uint32_t count = __count;
-    __enable_irq();
+    NVIC_EnableIRQ(PIT_IRQn); //END CRITICAL SECTION
     
     //Convert to ticks
-    return (uint32_t) count * __rolloverValue + tick;
+    return (__rolloverValue - tick) + count * __rolloverValue;
 }
 
-void Timer_PIT::__set_pit(uint32_t count) {
-    PIT->CHANNEL[0].LDVAL = count; //Load the countdown value. PIT counts downwards.
+void Timer_PIT::__init_timer() {        
+    SIM->SCGC6 |= SIM_SCGC6_PIT_MASK;   //Enable clocking of PIT
+    
+    PIT->MCR |= PIT_MCR_MDIS_MASK; //Setting MDIS bit disables the timer module.
+    
+    //Set interrupt handler
+    NVIC_SetVector(PIT_IRQn, (uint32_t) __pit_isr_wrapper);
+    NVIC_EnableIRQ(PIT_IRQn);
+    
+    PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TIE_MASK; //Enable interrupts
+    
+    PIT->MCR &= ~PIT_MCR_MDIS_MASK; //Clearing MDIS bit enables the timer module.
+
+    //Good to go!
+}
+
+void Timer_PIT::__start_timer() {
+    PIT->CHANNEL[0].LDVAL = __rolloverValue; //Load the countdown value. PIT counts downwards.
     PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TEN_MASK; //Enable the timer.
 }
 
-void Timer_PIT::__isr_pit() {
+void Timer_PIT::__stop_timer() {
+    PIT->MCR |= PIT_MCR_MDIS_MASK; //Setting MDIS bit disables the timer.
+}
+
+void Timer_PIT::__timer_isr() {
     PIT->CHANNEL[0].TFLG |= PIT_TFLG_TIF_MASK; //Clear the timer interrupt flag bit
+    if ((__periodic || __call_user_function) && __user_fptr != NULL) { //user callback
+        __user_fptr->call();
+        __call_user_function = false;
+    }   
     __count++;
+}
+
+void Timer_PIT::__pit_isr_wrapper() {
+    __obj->__timer_isr();   
 }
\ No newline at end of file