Mark Gottscho / HardwareTimersLib

Fork of HardwareTimersLib by Mark Gottscho

Committer:
mgottscho
Date:
Tue Mar 11 05:38:56 2014 +0000
Revision:
12:cb395e4be69e
Parent:
11:e0442c8b182b
Enabled a new mode for the timers. You can now do indefinite periodic callbacks, or a limited number using HardwareTimer::start(). Also got rid of C functions for PIT management.

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 9:dff7c891ec77 39 uint32_t tick;
mgottscho 9:dff7c891ec77 40 uint32_t count;
mgottscho 9:dff7c891ec77 41
mgottscho 11:e0442c8b182b 42 //__disable_irq(); //CRITICAL SECTION -- ALL INTERRUPTS MUST BE STOPPED!
mgottscho 9:dff7c891ec77 43 tick = PIT->CHANNEL[0].CVAL; //counts down
mgottscho 11:e0442c8b182b 44
mgottscho 11:e0442c8b182b 45 //It is theoretically possible that the timer interrupt is invoked here, between these two lines.
mgottscho 11:e0442c8b182b 46 //However, the timer doesn't appear to work properly if I put these two in a critical section.
mgottscho 11:e0442c8b182b 47
mgottscho 9:dff7c891ec77 48 count = __count;
mgottscho 11:e0442c8b182b 49 //__enable_irq(); //END CRITICAL SECTION
mgottscho 9:dff7c891ec77 50
mgottscho 2:5056ec8c52e8 51 //Convert to ticks
mgottscho 7:78f6ee57d324 52 return (__rolloverValue - tick) + count * __rolloverValue;
mgottscho 2:5056ec8c52e8 53 }
mgottscho 2:5056ec8c52e8 54
mgottscho 7:78f6ee57d324 55 void Timer_PIT::__init_timer() {
mgottscho 7:78f6ee57d324 56 SIM->SCGC6 |= SIM_SCGC6_PIT_MASK; //Enable clocking of PIT
mgottscho 7:78f6ee57d324 57
mgottscho 7:78f6ee57d324 58 PIT->MCR |= PIT_MCR_MDIS_MASK; //Setting MDIS bit disables the timer module.
mgottscho 7:78f6ee57d324 59
mgottscho 7:78f6ee57d324 60 //Set interrupt handler
mgottscho 7:78f6ee57d324 61 NVIC_SetVector(PIT_IRQn, (uint32_t) __pit_isr_wrapper);
mgottscho 7:78f6ee57d324 62 NVIC_EnableIRQ(PIT_IRQn);
mgottscho 7:78f6ee57d324 63
mgottscho 7:78f6ee57d324 64 PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TIE_MASK; //Enable interrupts
mgottscho 7:78f6ee57d324 65
mgottscho 7:78f6ee57d324 66 PIT->MCR &= ~PIT_MCR_MDIS_MASK; //Clearing MDIS bit enables the timer module.
mgottscho 7:78f6ee57d324 67
mgottscho 7:78f6ee57d324 68 //Good to go!
mgottscho 7:78f6ee57d324 69 }
mgottscho 7:78f6ee57d324 70
mgottscho 7:78f6ee57d324 71 void Timer_PIT::__start_timer() {
mgottscho 7:78f6ee57d324 72 PIT->CHANNEL[0].LDVAL = __rolloverValue; //Load the countdown value. PIT counts downwards.
mgottscho 2:5056ec8c52e8 73 PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TEN_MASK; //Enable the timer.
mgottscho 2:5056ec8c52e8 74 }
mgottscho 2:5056ec8c52e8 75
mgottscho 7:78f6ee57d324 76 void Timer_PIT::__stop_timer() {
mgottscho 9:dff7c891ec77 77 PIT->CHANNEL[0].TCTRL &= ~PIT_TCTRL_TEN_MASK; //Disable the timer.
mgottscho 7:78f6ee57d324 78 }
mgottscho 7:78f6ee57d324 79
mgottscho 7:78f6ee57d324 80 void Timer_PIT::__timer_isr() {
mgottscho 2:5056ec8c52e8 81 PIT->CHANNEL[0].TFLG |= PIT_TFLG_TIF_MASK; //Clear the timer interrupt flag bit
mgottscho 12:cb395e4be69e 82 if ((__periodic || __num_callbacks > 0) && __user_fptr != NULL) { //user callback
mgottscho 7:78f6ee57d324 83 __user_fptr->call();
mgottscho 12:cb395e4be69e 84 if (!__periodic)
mgottscho 12:cb395e4be69e 85 __num_callbacks--;
mgottscho 7:78f6ee57d324 86 }
mgottscho 2:5056ec8c52e8 87 __count++;
mgottscho 7:78f6ee57d324 88 }
mgottscho 7:78f6ee57d324 89
mgottscho 7:78f6ee57d324 90 void Timer_PIT::__pit_isr_wrapper() {
mgottscho 7:78f6ee57d324 91 __obj->__timer_isr();
mgottscho 2:5056ec8c52e8 92 }