Mark Gottscho / HardwareTimersLib

Fork of HardwareTimersLib by Mark Gottscho

Committer:
mgottscho
Date:
Tue Mar 11 02:42:03 2014 +0000
Revision:
8:23c04123395c
Parent:
7:78f6ee57d324
Child:
9:dff7c891ec77
All timers now globally disable interrupts during computation of getTick(). If this is not done, the tick count will be corrupted.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mgottscho 2:5056ec8c52e8 1 /* Timer_PIT.cpp
mgottscho 2:5056ec8c52e8 2 * Tested with mbed board: FRDM-KL46Z
mgottscho 2:5056ec8c52e8 3 * Author: Mark Gottscho
mgottscho 2:5056ec8c52e8 4 * mgottscho@ucla.edu
mgottscho 2:5056ec8c52e8 5 */
mgottscho 2:5056ec8c52e8 6
mgottscho 2:5056ec8c52e8 7 #include "mbed.h"
mgottscho 2:5056ec8c52e8 8 #include "HardwareTimer.h"
mgottscho 2:5056ec8c52e8 9 #include "Timer_PIT.h"
mgottscho 2:5056ec8c52e8 10
mgottscho 7:78f6ee57d324 11
mgottscho 7:78f6ee57d324 12 //Init Timer_PIT class variables
mgottscho 7:78f6ee57d324 13 bool Timer_PIT::__pit_used = false;
mgottscho 7:78f6ee57d324 14 Timer_PIT *Timer_PIT::__obj = NULL;
mgottscho 2:5056ec8c52e8 15
mgottscho 7:78f6ee57d324 16 Timer_PIT::Timer_PIT() :
mgottscho 7:78f6ee57d324 17 HardwareTimer(0xFFFFFFFF, 41.666666666, HardwareTimer::ns) //PIT has 32-bit counter. And at 24 MHz, each clock cycle is 41.666666 ns
mgottscho 2:5056ec8c52e8 18 {
mgottscho 7:78f6ee57d324 19 if (__pit_used)
mgottscho 7:78f6ee57d324 20 __valid = false;
mgottscho 7:78f6ee57d324 21 else {
mgottscho 7:78f6ee57d324 22 __valid = true;
mgottscho 7:78f6ee57d324 23 __pit_used = true;
mgottscho 7:78f6ee57d324 24 __obj = this;
mgottscho 7:78f6ee57d324 25 }
mgottscho 2:5056ec8c52e8 26 }
mgottscho 2:5056ec8c52e8 27
mgottscho 7:78f6ee57d324 28 Timer_PIT::~Timer_PIT() {
mgottscho 7:78f6ee57d324 29 if (__valid) {
mgottscho 7:78f6ee57d324 30 __pit_used = false; //free the hardware PIT resource
mgottscho 7:78f6ee57d324 31 __obj = NULL;
mgottscho 7:78f6ee57d324 32 }
mgottscho 2:5056ec8c52e8 33 }
mgottscho 2:5056ec8c52e8 34
mgottscho 2:5056ec8c52e8 35 uint32_t Timer_PIT::getTick() {
mgottscho 2:5056ec8c52e8 36 if (!__valid)
mgottscho 2:5056ec8c52e8 37 return 0;
mgottscho 2:5056ec8c52e8 38
mgottscho 8:23c04123395c 39 // CRITICAL SECTION -- ALL INTERRUPTS MUST BE STOPPED!
mgottscho 8:23c04123395c 40 __disable_irq();
mgottscho 7:78f6ee57d324 41 uint32_t tick = PIT->CHANNEL[0].CVAL; //counts down
mgottscho 2:5056ec8c52e8 42 uint32_t count = __count;
mgottscho 8:23c04123395c 43 __enable_irq();
mgottscho 8:23c04123395c 44 // END CRITICAL SECTION
mgottscho 2:5056ec8c52e8 45
mgottscho 2:5056ec8c52e8 46 //Convert to ticks
mgottscho 7:78f6ee57d324 47 return (__rolloverValue - tick) + count * __rolloverValue;
mgottscho 2:5056ec8c52e8 48 }
mgottscho 2:5056ec8c52e8 49
mgottscho 7:78f6ee57d324 50 void Timer_PIT::__init_timer() {
mgottscho 7:78f6ee57d324 51 SIM->SCGC6 |= SIM_SCGC6_PIT_MASK; //Enable clocking of PIT
mgottscho 7:78f6ee57d324 52
mgottscho 7:78f6ee57d324 53 PIT->MCR |= PIT_MCR_MDIS_MASK; //Setting MDIS bit disables the timer module.
mgottscho 7:78f6ee57d324 54
mgottscho 7:78f6ee57d324 55 //Set interrupt handler
mgottscho 7:78f6ee57d324 56 NVIC_SetVector(PIT_IRQn, (uint32_t) __pit_isr_wrapper);
mgottscho 7:78f6ee57d324 57 NVIC_EnableIRQ(PIT_IRQn);
mgottscho 7:78f6ee57d324 58
mgottscho 7:78f6ee57d324 59 PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TIE_MASK; //Enable interrupts
mgottscho 7:78f6ee57d324 60
mgottscho 7:78f6ee57d324 61 PIT->MCR &= ~PIT_MCR_MDIS_MASK; //Clearing MDIS bit enables the timer module.
mgottscho 7:78f6ee57d324 62
mgottscho 7:78f6ee57d324 63 //Good to go!
mgottscho 7:78f6ee57d324 64 }
mgottscho 7:78f6ee57d324 65
mgottscho 7:78f6ee57d324 66 void Timer_PIT::__start_timer() {
mgottscho 7:78f6ee57d324 67 PIT->CHANNEL[0].LDVAL = __rolloverValue; //Load the countdown value. PIT counts downwards.
mgottscho 2:5056ec8c52e8 68 PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TEN_MASK; //Enable the timer.
mgottscho 2:5056ec8c52e8 69 }
mgottscho 2:5056ec8c52e8 70
mgottscho 7:78f6ee57d324 71 void Timer_PIT::__stop_timer() {
mgottscho 7:78f6ee57d324 72 PIT->MCR |= PIT_MCR_MDIS_MASK; //Setting MDIS bit disables the timer.
mgottscho 7:78f6ee57d324 73 }
mgottscho 7:78f6ee57d324 74
mgottscho 7:78f6ee57d324 75 void Timer_PIT::__timer_isr() {
mgottscho 2:5056ec8c52e8 76 PIT->CHANNEL[0].TFLG |= PIT_TFLG_TIF_MASK; //Clear the timer interrupt flag bit
mgottscho 7:78f6ee57d324 77 if ((__periodic || __call_user_function) && __user_fptr != NULL) { //user callback
mgottscho 7:78f6ee57d324 78 __user_fptr->call();
mgottscho 7:78f6ee57d324 79 __call_user_function = false;
mgottscho 7:78f6ee57d324 80 }
mgottscho 2:5056ec8c52e8 81 __count++;
mgottscho 7:78f6ee57d324 82 }
mgottscho 7:78f6ee57d324 83
mgottscho 7:78f6ee57d324 84 void Timer_PIT::__pit_isr_wrapper() {
mgottscho 7:78f6ee57d324 85 __obj->__timer_isr();
mgottscho 2:5056ec8c52e8 86 }