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:
12:cb395e4be69e
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 0:47acc8320421 1 /* HardwareTimer.cpp
mgottscho 0:47acc8320421 2 * Tested with mbed board: FRDM-KL46Z
mgottscho 0:47acc8320421 3 * Author: Mark Gottscho
mgottscho 0:47acc8320421 4 * mgottscho@ucla.edu
mgottscho 0:47acc8320421 5 */
mgottscho 0:47acc8320421 6
mgottscho 0:47acc8320421 7 #include "mbed.h"
mgottscho 0:47acc8320421 8 #include "HardwareTimer.h"
mgottscho 0:47acc8320421 9
mgottscho 7:78f6ee57d324 10 HardwareTimer::HardwareTimer(uint32_t maxRolloverTick, float tickValue, tick_units_t tickUnits) :
mgottscho 0:47acc8320421 11 __valid(false),
mgottscho 7:78f6ee57d324 12 __count(0),
mgottscho 7:78f6ee57d324 13 __rolloverValue(0),
mgottscho 7:78f6ee57d324 14 __periodic(false),
mgottscho 7:78f6ee57d324 15 __call_user_function(false),
mgottscho 7:78f6ee57d324 16 __user_fptr(NULL),
mgottscho 0:47acc8320421 17 __enabled(false),
mgottscho 7:78f6ee57d324 18 __running(false),
mgottscho 7:78f6ee57d324 19 __maxRolloverTick(maxRolloverTick),
mgottscho 7:78f6ee57d324 20 __tickValue(tickValue),
mgottscho 7:78f6ee57d324 21 __tickUnits(tickUnits)
mgottscho 0:47acc8320421 22 {
mgottscho 0:47acc8320421 23 }
mgottscho 0:47acc8320421 24
mgottscho 7:78f6ee57d324 25 HardwareTimer::~HardwareTimer() {
mgottscho 7:78f6ee57d324 26 disable();
mgottscho 7:78f6ee57d324 27 if (__user_fptr != NULL) //double check
mgottscho 7:78f6ee57d324 28 delete __user_fptr;
mgottscho 7:78f6ee57d324 29 }
mgottscho 0:47acc8320421 30
mgottscho 0:47acc8320421 31 bool HardwareTimer::valid() {
mgottscho 0:47acc8320421 32 return __valid;
mgottscho 0:47acc8320421 33 }
mgottscho 0:47acc8320421 34
mgottscho 7:78f6ee57d324 35 bool HardwareTimer::enabled() {
mgottscho 0:47acc8320421 36 return __enabled;
mgottscho 0:47acc8320421 37 }
mgottscho 0:47acc8320421 38
mgottscho 7:78f6ee57d324 39 bool HardwareTimer::running() {
mgottscho 7:78f6ee57d324 40 return __running;
mgottscho 7:78f6ee57d324 41 }
mgottscho 7:78f6ee57d324 42
mgottscho 0:47acc8320421 43 float HardwareTimer::tickValue() {
mgottscho 0:47acc8320421 44 return __tickValue;
mgottscho 7:78f6ee57d324 45 }
mgottscho 7:78f6ee57d324 46
mgottscho 7:78f6ee57d324 47 float HardwareTimer::tickUnits() {
mgottscho 7:78f6ee57d324 48 switch (__tickUnits) {
mgottscho 7:78f6ee57d324 49 default:
mgottscho 7:78f6ee57d324 50 case ns:
mgottscho 7:78f6ee57d324 51 return 1e-9;
mgottscho 7:78f6ee57d324 52 case us:
mgottscho 7:78f6ee57d324 53 return 1e-6;
mgottscho 7:78f6ee57d324 54 case ms:
mgottscho 7:78f6ee57d324 55 return 1e-3;
mgottscho 7:78f6ee57d324 56 case s:
mgottscho 7:78f6ee57d324 57 return 1;
mgottscho 7:78f6ee57d324 58 case m:
mgottscho 7:78f6ee57d324 59 return 60;
mgottscho 7:78f6ee57d324 60 case h:
mgottscho 7:78f6ee57d324 61 return 3600;
mgottscho 7:78f6ee57d324 62 }
mgottscho 7:78f6ee57d324 63 }
mgottscho 7:78f6ee57d324 64
mgottscho 7:78f6ee57d324 65 void HardwareTimer::enable(void (*fptr)(void)) {
mgottscho 7:78f6ee57d324 66 if (!__valid)
mgottscho 7:78f6ee57d324 67 return;
mgottscho 7:78f6ee57d324 68
mgottscho 7:78f6ee57d324 69 //set user function pointer
mgottscho 7:78f6ee57d324 70 if (__user_fptr != NULL)
mgottscho 7:78f6ee57d324 71 delete __user_fptr;
mgottscho 7:78f6ee57d324 72 if (fptr != NULL)
mgottscho 7:78f6ee57d324 73 __user_fptr = new FunctionPointer(fptr);
mgottscho 7:78f6ee57d324 74
mgottscho 7:78f6ee57d324 75 __init_timer(); //Do hardware-specific initialization
mgottscho 7:78f6ee57d324 76
mgottscho 7:78f6ee57d324 77 __enabled = true;
mgottscho 7:78f6ee57d324 78 }
mgottscho 7:78f6ee57d324 79
mgottscho 7:78f6ee57d324 80
mgottscho 7:78f6ee57d324 81 template <typename T> void HardwareTimer::enable(T *tptr, void (T::*mptr)(void)) {
mgottscho 7:78f6ee57d324 82 if (!__valid)
mgottscho 7:78f6ee57d324 83 return;
mgottscho 8:23c04123395c 84
mgottscho 8:23c04123395c 85 if (__enabled)
mgottscho 8:23c04123395c 86 disable();
mgottscho 8:23c04123395c 87 __user_fptr = new FunctionPointer(tptr, mptr);
mgottscho 7:78f6ee57d324 88
mgottscho 7:78f6ee57d324 89 __init_timer(); //Do hardware-specific initialization
mgottscho 7:78f6ee57d324 90
mgottscho 7:78f6ee57d324 91 __enabled = true;
mgottscho 7:78f6ee57d324 92 }
mgottscho 7:78f6ee57d324 93
mgottscho 7:78f6ee57d324 94 void HardwareTimer::disable() {
mgottscho 7:78f6ee57d324 95 if (!__valid)
mgottscho 7:78f6ee57d324 96 return;
mgottscho 7:78f6ee57d324 97
mgottscho 7:78f6ee57d324 98 __stop_timer(); //Do hardware-specific stop
mgottscho 7:78f6ee57d324 99 __running = false;
mgottscho 7:78f6ee57d324 100
mgottscho 7:78f6ee57d324 101 if (__user_fptr != NULL) //Detach user callback function
mgottscho 7:78f6ee57d324 102 delete __user_fptr;
mgottscho 7:78f6ee57d324 103 __user_fptr = NULL;
mgottscho 7:78f6ee57d324 104
mgottscho 7:78f6ee57d324 105 __enabled = false;
mgottscho 7:78f6ee57d324 106 }
mgottscho 7:78f6ee57d324 107
mgottscho 7:78f6ee57d324 108 void HardwareTimer::start(uint32_t callback_tick_count, bool periodic) {
mgottscho 7:78f6ee57d324 109 if (!__valid || !__enabled || callback_tick_count > __maxRolloverTick)
mgottscho 7:78f6ee57d324 110 return;
mgottscho 7:78f6ee57d324 111
mgottscho 8:23c04123395c 112 __stop_timer();
mgottscho 8:23c04123395c 113 __running = false;
mgottscho 8:23c04123395c 114
mgottscho 7:78f6ee57d324 115 __periodic = periodic;
mgottscho 7:78f6ee57d324 116 __rolloverValue = callback_tick_count;
mgottscho 8:23c04123395c 117
mgottscho 7:78f6ee57d324 118 __start_timer(); //Do hardware-specific start
mgottscho 7:78f6ee57d324 119 __running = true;
mgottscho 7:78f6ee57d324 120 }
mgottscho 7:78f6ee57d324 121
mgottscho 7:78f6ee57d324 122 uint32_t HardwareTimer::getMaxCallbackTickCount() {
mgottscho 7:78f6ee57d324 123 return __maxRolloverTick;
mgottscho 7:78f6ee57d324 124 }
mgottscho 7:78f6ee57d324 125
mgottscho 7:78f6ee57d324 126 PreciseTime HardwareTimer::getTime() {
mgottscho 7:78f6ee57d324 127 if (!__valid)
mgottscho 7:78f6ee57d324 128 return PreciseTime();
mgottscho 7:78f6ee57d324 129
mgottscho 7:78f6ee57d324 130 uint32_t tick = getTick();
mgottscho 7:78f6ee57d324 131 uint32_t converted_ticks = tick * __tickValue;
mgottscho 7:78f6ee57d324 132
mgottscho 7:78f6ee57d324 133 switch (__tickUnits) {
mgottscho 7:78f6ee57d324 134 default:
mgottscho 7:78f6ee57d324 135 case ns:
mgottscho 7:78f6ee57d324 136 return PreciseTime::from_ns(converted_ticks);
mgottscho 7:78f6ee57d324 137 case us:
mgottscho 7:78f6ee57d324 138 return PreciseTime::from_us(converted_ticks);
mgottscho 7:78f6ee57d324 139 case ms:
mgottscho 7:78f6ee57d324 140 return PreciseTime::from_ms(converted_ticks);
mgottscho 7:78f6ee57d324 141 case s:
mgottscho 7:78f6ee57d324 142 return PreciseTime::from_s(converted_ticks);
mgottscho 7:78f6ee57d324 143 case m:
mgottscho 7:78f6ee57d324 144 return PreciseTime::from_m(converted_ticks);
mgottscho 7:78f6ee57d324 145 case h:
mgottscho 7:78f6ee57d324 146 return PreciseTime::from_h(converted_ticks);
mgottscho 7:78f6ee57d324 147 }
mgottscho 0:47acc8320421 148 }