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:
1:0b44a0a56f92
fix

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elevatorguy 0:d2d9baa1a6d8 1 #include "Ticker.h"
elevatorguy 0:d2d9baa1a6d8 2 //This class uses Timer 2
elevatorguy 0:d2d9baa1a6d8 3
elevatorguy 0:d2d9baa1a6d8 4 extern "C" void TIMER2_IRQHandler(void)
elevatorguy 0:d2d9baa1a6d8 5 {
elevatorguy 0:d2d9baa1a6d8 6 if ( LPC_TIM2->IR & 0x1 )
elevatorguy 0:d2d9baa1a6d8 7 {
elevatorguy 0:d2d9baa1a6d8 8 LPC_TIM2->IR = 0x1; /* clear interrupt flag */
elevatorguy 0:d2d9baa1a6d8 9 for(char count = 0; count < Ticker::active_tickers; count++)
elevatorguy 0:d2d9baa1a6d8 10 {
elevatorguy 0:d2d9baa1a6d8 11 if((*(Ticker::tickers[count])).active)
elevatorguy 0:d2d9baa1a6d8 12 {
elevatorguy 0:d2d9baa1a6d8 13 if((*(Ticker::tickers[count])).remaining == 0)
elevatorguy 0:d2d9baa1a6d8 14 {
elevatorguy 0:d2d9baa1a6d8 15 //void (*func)(void) = (void (*)(void))((uint32_t)&isr);
elevatorguy 0:d2d9baa1a6d8 16 //func();
elevatorguy 0:d2d9baa1a6d8 17 (*(void (*)(void))((*(Ticker::tickers[count])).func))();
elevatorguy 0:d2d9baa1a6d8 18
elevatorguy 0:d2d9baa1a6d8 19 if((*(Ticker::tickers[count])).timeout)
elevatorguy 0:d2d9baa1a6d8 20 (*(Ticker::tickers[count])).active = false;
elevatorguy 0:d2d9baa1a6d8 21 else
elevatorguy 0:d2d9baa1a6d8 22 (*(Ticker::tickers[count])).remaining = (*(Ticker::tickers[count])).interval - 1; //set up for next interval
elevatorguy 0:d2d9baa1a6d8 23 }
elevatorguy 0:d2d9baa1a6d8 24 else
elevatorguy 0:d2d9baa1a6d8 25 {
elevatorguy 0:d2d9baa1a6d8 26 (*(Ticker::tickers[count])).remaining = (*(Ticker::tickers[count])).remaining - 1;
elevatorguy 0:d2d9baa1a6d8 27 }
elevatorguy 0:d2d9baa1a6d8 28 }
elevatorguy 0:d2d9baa1a6d8 29 }
elevatorguy 0:d2d9baa1a6d8 30 }
elevatorguy 0:d2d9baa1a6d8 31 }
elevatorguy 0:d2d9baa1a6d8 32
elevatorguy 0:d2d9baa1a6d8 33 // static data initialization (only called once)
elevatorguy 0:d2d9baa1a6d8 34 bool Ticker::timer2initialized = false;
elevatorguy 0:d2d9baa1a6d8 35 int Ticker::active_tickers = 0;
elevatorguy 0:d2d9baa1a6d8 36 int Ticker::MAX = 5;
elevatorguy 0:d2d9baa1a6d8 37 Ticker** Ticker::tickers = 0; //NULL POINTER
elevatorguy 0:d2d9baa1a6d8 38
elevatorguy 0:d2d9baa1a6d8 39 void Ticker::initTimer2()
elevatorguy 0:d2d9baa1a6d8 40 {
elevatorguy 0:d2d9baa1a6d8 41 LPC_SC->PCLKSEL1 &= (3 << 12); //mask
elevatorguy 0:d2d9baa1a6d8 42 LPC_SC->PCLKSEL1 |= (1 << 12); //sets it to 1*SystemCoreClock - table 42 (page 57 in user manual)
elevatorguy 0:d2d9baa1a6d8 43
elevatorguy 0:d2d9baa1a6d8 44 LPC_SC->PCONP |= (0x1<<22); // turn on power for timer 2
elevatorguy 0:d2d9baa1a6d8 45 LPC_TIM2->TCR = 0x02; // reset timer
elevatorguy 0:d2d9baa1a6d8 46 LPC_TIM2->PR = (SystemCoreClock / 1000000); //microsecond steps
elevatorguy 0:d2d9baa1a6d8 47 LPC_TIM2->MR0 = 100; // 100 microsecond interval interrupts
elevatorguy 0:d2d9baa1a6d8 48 LPC_TIM2->IR = 0x3f; // reset all interrrupts
elevatorguy 0:d2d9baa1a6d8 49 LPC_TIM2->MCR = 0x03; // reset timer on match and generate interrupt (MR0)
elevatorguy 0:d2d9baa1a6d8 50 LPC_TIM2->TCR = 0x01; // start timer
elevatorguy 0:d2d9baa1a6d8 51
elevatorguy 0:d2d9baa1a6d8 52 NVIC_EnableIRQ(TIMER2_IRQn); // Enable the interrupt
elevatorguy 0:d2d9baa1a6d8 53
elevatorguy 0:d2d9baa1a6d8 54 timer2initialized = true;
elevatorguy 0:d2d9baa1a6d8 55 }
elevatorguy 0:d2d9baa1a6d8 56
elevatorguy 0:d2d9baa1a6d8 57 Ticker::Ticker()
elevatorguy 0:d2d9baa1a6d8 58 {
elevatorguy 0:d2d9baa1a6d8 59 if(!timer2initialized)
elevatorguy 0:d2d9baa1a6d8 60 {
elevatorguy 0:d2d9baa1a6d8 61 initTimer2();
elevatorguy 0:d2d9baa1a6d8 62 tickers = new Ticker*[MAX];
elevatorguy 0:d2d9baa1a6d8 63 }
elevatorguy 0:d2d9baa1a6d8 64 active = false;
elevatorguy 0:d2d9baa1a6d8 65 timeout = false;
elevatorguy 0:d2d9baa1a6d8 66 }
elevatorguy 0:d2d9baa1a6d8 67
elevatorguy 0:d2d9baa1a6d8 68 Ticker::Ticker(int maxsize)
elevatorguy 0:d2d9baa1a6d8 69 {
elevatorguy 0:d2d9baa1a6d8 70 if(!timer2initialized)
elevatorguy 0:d2d9baa1a6d8 71 {
elevatorguy 0:d2d9baa1a6d8 72 initTimer2();
elevatorguy 0:d2d9baa1a6d8 73 tickers = new Ticker*[maxsize];
elevatorguy 0:d2d9baa1a6d8 74 MAX = maxsize;
elevatorguy 0:d2d9baa1a6d8 75 }
elevatorguy 0:d2d9baa1a6d8 76 active = false;
elevatorguy 0:d2d9baa1a6d8 77 timeout = false;
elevatorguy 0:d2d9baa1a6d8 78 }
elevatorguy 0:d2d9baa1a6d8 79
elevatorguy 0:d2d9baa1a6d8 80 void Ticker::attach(void (*funcaddr)(void), float secinterval)
elevatorguy 0:d2d9baa1a6d8 81 {
elevatorguy 1:0b44a0a56f92 82 if(active_tickers < MAX)
elevatorguy 1:0b44a0a56f92 83 {
elevatorguy 1:0b44a0a56f92 84 func = (uint32_t)funcaddr; //pointer to function address
elevatorguy 1:0b44a0a56f92 85 interval = secinterval*10000;
elevatorguy 2:276fb0fe230c 86 remaining = secinterval*10000; // 100 microsecond resolution
elevatorguy 1:0b44a0a56f92 87 tickers[active_tickers] = this;
elevatorguy 1:0b44a0a56f92 88 active_tickers = active_tickers + 1;
elevatorguy 1:0b44a0a56f92 89 active = true;
elevatorguy 1:0b44a0a56f92 90 }
elevatorguy 0:d2d9baa1a6d8 91 }
elevatorguy 0:d2d9baa1a6d8 92
elevatorguy 0:d2d9baa1a6d8 93 void Ticker::detach()
elevatorguy 0:d2d9baa1a6d8 94 {
elevatorguy 0:d2d9baa1a6d8 95 active_tickers = active_tickers - 1;
elevatorguy 0:d2d9baa1a6d8 96 tickers[active_tickers] = 0; //NULL pointer
elevatorguy 0:d2d9baa1a6d8 97 active = false;
elevatorguy 1:0b44a0a56f92 98 timeout = false;
elevatorguy 0:d2d9baa1a6d8 99 }
elevatorguy 0:d2d9baa1a6d8 100
elevatorguy 0:d2d9baa1a6d8 101 Ticker::~Ticker()
elevatorguy 0:d2d9baa1a6d8 102 {
elevatorguy 0:d2d9baa1a6d8 103 if(active || timeout)
elevatorguy 0:d2d9baa1a6d8 104 detach();
elevatorguy 0:d2d9baa1a6d8 105 }