my implementation of mbed-like classes using the LPC1768 register access.

Dependents:   registers-example RedWireBridge

This is just to satisfy my curiosity on how the mbed libraries work. I put it here just in case others are too. Every time I learn how another internal register works, I'll keep it here to save myself from future coding headaches.

working

  • DigitalIn
  • DigitalOut
  • wait()

mostly working

  • Serial
  • Timer
  • Ticker
  • Timeout

Serial doesn't have all the methods that mbed had, but it works for me. (only UART0, so only over USB to the pc for now) Timer has the same limitations of mbed for default resolution (30 min limit), and if you start at the end of resolution and stop after it rolls back to 0, it doesn't take that into account. But I added the option to change resolution, so I can have longer timers.

For Ticker, I used a 100 microsecond timer instead of a 1 microsecond Timer, so the smallest interval in between function calls is 100 microseconds. (10KHz) However, this means that the maximum interval in between function calls is 59 hours. (untested)

The Timeout class, simply uses a Ticker, but then marks it as nonactive after the first function call. Automatically calls the detach() function when attaching it again, so no don't need to worry about it.

Committer:
elevatorguy
Date:
Thu Jan 03 05:25:18 2013 +0000
Revision:
2:276fb0fe230c
Parent:
0:d2d9baa1a6d8
fix

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elevatorguy 0:d2d9baa1a6d8 1 #include "Timer.h"
elevatorguy 0:d2d9baa1a6d8 2 //This class uses Timer 1
elevatorguy 0:d2d9baa1a6d8 3
elevatorguy 0:d2d9baa1a6d8 4 // static data initialization (only called once)
elevatorguy 0:d2d9baa1a6d8 5 bool Timer::timer1initialized = false;
elevatorguy 0:d2d9baa1a6d8 6 int Timer::resolution = 1000000; //default: microseconds accuracy
elevatorguy 0:d2d9baa1a6d8 7
elevatorguy 0:d2d9baa1a6d8 8 void Timer::initTimer1(int res)
elevatorguy 0:d2d9baa1a6d8 9 {
elevatorguy 0:d2d9baa1a6d8 10 uint8_t pclk;
elevatorguy 0:d2d9baa1a6d8 11 uint32_t pclkdiv = (LPC_SC->PCLKSEL0 >> 4) & 0x03; //PCLK for Timer 1 (page 56)
elevatorguy 0:d2d9baa1a6d8 12
elevatorguy 0:d2d9baa1a6d8 13 switch ( pclkdiv ) // table 42 (page 57 in user manual)
elevatorguy 0:d2d9baa1a6d8 14 {
elevatorguy 0:d2d9baa1a6d8 15 case 0x00:
elevatorguy 0:d2d9baa1a6d8 16 default:
elevatorguy 0:d2d9baa1a6d8 17 pclk = 4;
elevatorguy 0:d2d9baa1a6d8 18 break;
elevatorguy 0:d2d9baa1a6d8 19 case 0x01:
elevatorguy 0:d2d9baa1a6d8 20 pclk = 1;
elevatorguy 0:d2d9baa1a6d8 21 break;
elevatorguy 0:d2d9baa1a6d8 22 case 0x02:
elevatorguy 0:d2d9baa1a6d8 23 pclk = 2;
elevatorguy 0:d2d9baa1a6d8 24 break;
elevatorguy 0:d2d9baa1a6d8 25 case 0x03:
elevatorguy 0:d2d9baa1a6d8 26 pclk = 8;
elevatorguy 0:d2d9baa1a6d8 27 break;
elevatorguy 0:d2d9baa1a6d8 28 }
elevatorguy 0:d2d9baa1a6d8 29
elevatorguy 0:d2d9baa1a6d8 30 LPC_TIM1->TCR = 0x02; // reset timer
elevatorguy 0:d2d9baa1a6d8 31 LPC_TIM1->PR = (SystemCoreClock / (pclk * res)); //default: microsecond steps
elevatorguy 0:d2d9baa1a6d8 32 LPC_TIM1->MR0 = 2147483647; // highest number a 32bit signed int can store (for us ~ 35.79 minutes, or, for ms ~ 596.52 hours )
elevatorguy 0:d2d9baa1a6d8 33 LPC_TIM1->IR = 0xff; // reset all interrrupts
elevatorguy 0:d2d9baa1a6d8 34 LPC_TIM1->MCR = 0x02; // reset timer on match
elevatorguy 0:d2d9baa1a6d8 35 LPC_TIM1->TCR = 0x01; // start timer
elevatorguy 0:d2d9baa1a6d8 36
elevatorguy 0:d2d9baa1a6d8 37 // The timer simply goes on forever! It just resets itself when it hits the max number for TC
elevatorguy 0:d2d9baa1a6d8 38 timer1initialized = true;
elevatorguy 0:d2d9baa1a6d8 39 resolution = res;
elevatorguy 0:d2d9baa1a6d8 40 }
elevatorguy 0:d2d9baa1a6d8 41
elevatorguy 0:d2d9baa1a6d8 42 Timer::Timer()
elevatorguy 0:d2d9baa1a6d8 43 {
elevatorguy 0:d2d9baa1a6d8 44 if(!timer1initialized)
elevatorguy 0:d2d9baa1a6d8 45 {
elevatorguy 0:d2d9baa1a6d8 46 initTimer1(resolution); //default resolution
elevatorguy 0:d2d9baa1a6d8 47 }
elevatorguy 0:d2d9baa1a6d8 48
elevatorguy 0:d2d9baa1a6d8 49 starttime = 0;
elevatorguy 0:d2d9baa1a6d8 50 stoptime = 0;
elevatorguy 0:d2d9baa1a6d8 51 running = false;
elevatorguy 0:d2d9baa1a6d8 52 }
elevatorguy 0:d2d9baa1a6d8 53
elevatorguy 0:d2d9baa1a6d8 54 //for when we want to allow lower counting resolution, eg. milliseconds
elevatorguy 0:d2d9baa1a6d8 55 //so we can count longer than the 35 minutes with microsecond resolution
elevatorguy 0:d2d9baa1a6d8 56 Timer::Timer(int res) // millisecond, res = 1000
elevatorguy 0:d2d9baa1a6d8 57 {
elevatorguy 0:d2d9baa1a6d8 58 if(!timer1initialized)
elevatorguy 0:d2d9baa1a6d8 59 {
elevatorguy 0:d2d9baa1a6d8 60 initTimer1(res); //custom resolution
elevatorguy 0:d2d9baa1a6d8 61 }
elevatorguy 0:d2d9baa1a6d8 62
elevatorguy 0:d2d9baa1a6d8 63 starttime = 0;
elevatorguy 0:d2d9baa1a6d8 64 stoptime = 0;
elevatorguy 0:d2d9baa1a6d8 65 running = false;
elevatorguy 0:d2d9baa1a6d8 66 }
elevatorguy 0:d2d9baa1a6d8 67
elevatorguy 0:d2d9baa1a6d8 68 void Timer::start()
elevatorguy 0:d2d9baa1a6d8 69 {
elevatorguy 0:d2d9baa1a6d8 70 starttime = LPC_TIM1->TC;
elevatorguy 0:d2d9baa1a6d8 71 stoptime = 0; //clear previous stoptime
elevatorguy 0:d2d9baa1a6d8 72 running = true;
elevatorguy 0:d2d9baa1a6d8 73 }
elevatorguy 0:d2d9baa1a6d8 74
elevatorguy 0:d2d9baa1a6d8 75 void Timer::stop()
elevatorguy 0:d2d9baa1a6d8 76 {
elevatorguy 0:d2d9baa1a6d8 77 stoptime = LPC_TIM1->TC;
elevatorguy 0:d2d9baa1a6d8 78 running = false;
elevatorguy 0:d2d9baa1a6d8 79 }
elevatorguy 0:d2d9baa1a6d8 80
elevatorguy 0:d2d9baa1a6d8 81 void Timer::reset()
elevatorguy 0:d2d9baa1a6d8 82 {
elevatorguy 0:d2d9baa1a6d8 83 if(running)
elevatorguy 0:d2d9baa1a6d8 84 {
elevatorguy 0:d2d9baa1a6d8 85 starttime = LPC_TIM1->TC;
elevatorguy 0:d2d9baa1a6d8 86 }
elevatorguy 0:d2d9baa1a6d8 87 else
elevatorguy 0:d2d9baa1a6d8 88 {
elevatorguy 0:d2d9baa1a6d8 89 starttime = 0;
elevatorguy 0:d2d9baa1a6d8 90 }
elevatorguy 0:d2d9baa1a6d8 91
elevatorguy 0:d2d9baa1a6d8 92 stoptime = 0;
elevatorguy 0:d2d9baa1a6d8 93 }
elevatorguy 0:d2d9baa1a6d8 94
elevatorguy 0:d2d9baa1a6d8 95 float Timer::read()
elevatorguy 0:d2d9baa1a6d8 96 {
elevatorguy 0:d2d9baa1a6d8 97 if(running)
elevatorguy 0:d2d9baa1a6d8 98 {
elevatorguy 0:d2d9baa1a6d8 99 int currenttime = LPC_TIM1->TC;
elevatorguy 0:d2d9baa1a6d8 100 return (currenttime - starttime) / (resolution*1.0);
elevatorguy 0:d2d9baa1a6d8 101 }
elevatorguy 0:d2d9baa1a6d8 102 else // compare startime and stoptime
elevatorguy 0:d2d9baa1a6d8 103 {
elevatorguy 0:d2d9baa1a6d8 104 return (stoptime - starttime) / (resolution*1.0);
elevatorguy 0:d2d9baa1a6d8 105 }
elevatorguy 0:d2d9baa1a6d8 106 }
elevatorguy 0:d2d9baa1a6d8 107
elevatorguy 0:d2d9baa1a6d8 108 Timer::operator float()
elevatorguy 0:d2d9baa1a6d8 109 {
elevatorguy 0:d2d9baa1a6d8 110 return read();
elevatorguy 0:d2d9baa1a6d8 111 }