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.

Files at this revision

API Documentation at this revision

Comitter:
elevatorguy
Date:
Thu Jan 03 04:25:08 2013 +0000
Child:
1:0b44a0a56f92
Commit message:
library

Changed in this revision

DigitalIn.cpp Show annotated file Show diff for this revision Revisions of this file
DigitalIn.h Show annotated file Show diff for this revision Revisions of this file
DigitalOut.cpp Show annotated file Show diff for this revision Revisions of this file
DigitalOut.h Show annotated file Show diff for this revision Revisions of this file
InOut.cpp Show annotated file Show diff for this revision Revisions of this file
InOut.h Show annotated file Show diff for this revision Revisions of this file
Serial.cpp Show annotated file Show diff for this revision Revisions of this file
Serial.h Show annotated file Show diff for this revision Revisions of this file
Ticker.cpp Show annotated file Show diff for this revision Revisions of this file
Ticker.h Show annotated file Show diff for this revision Revisions of this file
Timeout.cpp Show annotated file Show diff for this revision Revisions of this file
Timeout.h Show annotated file Show diff for this revision Revisions of this file
Timer.cpp Show annotated file Show diff for this revision Revisions of this file
Timer.h Show annotated file Show diff for this revision Revisions of this file
functions.cpp Show annotated file Show diff for this revision Revisions of this file
functions.h Show annotated file Show diff for this revision Revisions of this file
registers.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DigitalIn.cpp	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,10 @@
+#include "DigitalIn.h"
+
+DigitalIn::DigitalIn(char mbedpin) : InOut(mbedpin, INPUT) {}
+
+// port, bit
+DigitalIn::DigitalIn(char p, char b) : InOut(p, b, INPUT) {}
+
+DigitalIn::operator bool() {
+    return read();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DigitalIn.h	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,16 @@
+#ifndef __DIGITALIN_H_
+#define __DIGITALIN_H_
+
+#include "LPC17xx.h"
+#include "InOut.h"
+
+class DigitalIn : public InOut
+{
+public:
+    DigitalIn(char); //mbed pin number
+    DigitalIn(char, char); // port and bit
+    
+    operator bool(); //read
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DigitalOut.cpp	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,15 @@
+#include "DigitalOut.h"
+
+DigitalOut::DigitalOut(char mbedpin) : InOut(mbedpin, OUTPUT) {}
+
+// port, bit
+DigitalOut::DigitalOut(char p, char b) : InOut(p, b, OUTPUT) {}
+
+DigitalOut::operator bool() {
+    return read();
+}
+DigitalOut& DigitalOut::operator=(bool value)
+{
+  write(value);
+  return *this;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DigitalOut.h	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,18 @@
+#ifndef __DIGITALOUT_H_
+#define __DIGITALOUT_H_
+
+#include "LPC17xx.h"
+#include "InOut.h"
+
+class DigitalOut : public InOut
+{
+public:
+    DigitalOut(char); //mbed pin number
+    DigitalOut(char, char); // port and bit
+    
+    //needs its own, since it doesn't automatically call the superclass' overloaded operators
+    DigitalOut& operator=(bool); //write
+    operator bool(); //read
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/InOut.cpp	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,372 @@
+#include "InOut.h"
+
+InOut::operator bool() {
+    return read();
+}
+InOut& InOut::operator=(bool value)
+{
+  write(value);
+  return *this;
+}
+
+// for the chip pins that the mbed didn't use
+InOut::InOut(char p, char b, bool output)
+{
+    port = p;
+    bit = b;
+    setDirection(output);
+}
+
+// the constructor takes the mbed pin number and then sets
+// the port and bit variables
+InOut::InOut(char mbedpin, bool output)
+{
+    port = 0;
+    switch(mbedpin)
+    {
+        case LED1:
+            port = 1;
+            bit = 18;
+            break;
+        case LED2:
+            port = 1;
+            bit = 20;
+            break;
+        case LED3:
+            port = 1;
+            bit = 21;
+            break;
+        case LED4:
+            port = 1;
+            bit = 23;
+            break;
+        case 19:
+            port = 1;
+            bit = 30;
+            break;
+        case 20:
+            port = 1;
+            bit = 31;
+            break;
+        case 21:
+            port = 2;
+            bit = 5;
+            break;   
+        case 22:
+            port = 2;
+            bit = 4;
+            break;    
+        case 23:
+            port = 2;
+            bit = 3;
+            break;    
+        case 24:
+            port = 2;
+            bit = 2;
+            break;    
+        case 25:
+            port = 2;
+            bit = 1;
+            break;    
+        case 26:
+            port = 2;
+            bit = 0;
+            break;                
+        case 5:
+            bit = 9;
+            break;
+        case 6:
+            bit = 8;
+            break;
+        case 7:
+            bit = 7;
+            break;
+        case 8:
+            bit = 6;
+            break;
+        case 9:
+            bit = 0;
+            break;
+        case 10:
+            bit = 1;
+            break;
+        case 11:
+            bit = 18;
+            break;
+        case 12:
+            bit = 17;
+            break;
+        case 13:
+            bit = 15;
+            break;
+        case 14:
+            bit = 16;
+            break;
+        case 15:
+            bit = 23;
+            break;
+        case 16:
+            bit = 24;
+            break;
+        case 17:
+            bit = 25;
+            break;
+        case 18:
+            bit = 26;
+            break;
+        case 27:
+            bit = 11;
+            break;
+        case 28:
+            bit = 10;
+            break;
+        case 29:
+            bit = 5;
+            break;
+        case 30:
+            bit = 4;
+            break;
+        default :
+            bit = NULL;
+            //fprintf(stderr, "pin %d is not on Port 0 or a LED\r\n", mbedpin);
+            break;
+    }
+    setDirection(output);
+}
+
+void InOut::output()
+{
+    setDirection(true);
+}
+
+void InOut::input()
+{
+    setDirection(false);
+}
+
+void InOut::setDirection(bool output)
+{
+    if(port==0)
+    {
+        if(output)
+        {
+            LPC_GPIO0->FIODIR |= (1 << bit); //sets pin to Output mode
+        }
+        else
+        {
+            LPC_GPIO0->FIODIR &= ~(1 << bit); //sets pin to Input mode
+        }
+    }
+    else if(port==1)
+    {
+        if(output)
+        {
+            LPC_GPIO1->FIODIR |= (1 << bit); //sets pin to Output mode
+        }
+        else
+        {
+            LPC_GPIO1->FIODIR &= ~(1 << bit); //sets pin to Input mode
+        }
+    }
+    else if(port==2)
+    {
+        if(output)
+        {
+            LPC_GPIO2->FIODIR |= (1 << bit); //sets pin to Output mode
+        }
+        else
+        {
+            LPC_GPIO2->FIODIR &= ~(1 << bit); //sets pin to Input mode
+        }
+    }
+}
+
+void InOut::write(bool state)
+{    
+    if(port==0)
+    {
+        if(state)
+        {
+            LPC_GPIO0->FIOPIN |= (1 << bit); //sets pin HIGH
+        }
+        else
+        {
+            LPC_GPIO0->FIOPIN &= ~(1 << bit); //sets pin LOW
+        }
+    }
+    else if(port==1)
+    {
+        if(state)
+        {
+            LPC_GPIO1->FIOPIN |= (1 << bit); //sets pin HIGH
+        }
+        else
+        {
+            LPC_GPIO1->FIOPIN &= ~(1 << bit); //sets pin LOW
+        }
+    }
+    else if(port==2)
+    {   
+        if(state)
+        {
+            LPC_GPIO2->FIOPIN |= (1 << bit); //sets pin HIGH
+        }
+        else
+        {
+            LPC_GPIO2->FIOPIN &= ~(1 << bit); //sets pin LOW
+        }
+    }
+}
+
+bool InOut::read(void)
+{
+    if(port==0)
+    {
+        return (LPC_GPIO0->FIOPIN >> bit) & 1; //returns the value of the pin (HIGH or LOW)
+    }
+    else if(port==1)
+    {
+        return (LPC_GPIO1->FIOPIN >> bit) & 1;
+    }
+    else if(port==2)
+    {
+        return (LPC_GPIO2->FIOPIN >> bit) & 1;
+    }
+    // else : SOL
+    
+    return 0;
+}
+
+void InOut::mode(char mode) // 0 for PullUp, 1 for PullDown and 2 for PullNone
+{
+    if(port==0)
+    {
+        if(bit < 16)
+        {
+            switch (mode)
+            {
+            case PULLDOWN:
+                LPC_PINCON->PINMODE0 |= (3 << (bit*2));
+                break;
+            case PULLUP:
+                LPC_PINCON->PINMODE0 &= ~(3 << (bit*2));
+                break;
+            case PULLNONE:
+                LPC_PINCON->PINMODE0 |= (1 << (bit*2));
+                LPC_PINCON->PINMODE0 &= ~(1 << ((bit*2)+1));
+                break;
+            case KEEPER:
+                LPC_PINCON->PINMODE0 &= ~(1 << (bit*2));
+                LPC_PINCON->PINMODE0 |= (1 << ((bit*2)+1));
+                break;
+            }
+        }
+        else
+        {
+            switch (mode)
+            {
+            case PULLDOWN:
+                LPC_PINCON->PINMODE1 |= (3 << (2*(bit-16)));
+                break;
+            case PULLUP:
+                LPC_PINCON->PINMODE1 &= ~(3 << (2*(bit-16)));
+                break;
+            case PULLNONE:
+                LPC_PINCON->PINMODE1 |= (1 << (2*(bit-16)));
+                LPC_PINCON->PINMODE1 &= ~(1 << ((2*(bit-16))+1));
+                break;
+            case KEEPER:
+                LPC_PINCON->PINMODE1 &= ~(1 << (2*(bit-16)));
+                LPC_PINCON->PINMODE1 |= (1 << ((2*(bit-16))+1));
+                break;
+            }
+        }
+    }
+    else if (port==1)
+    {
+        if(bit < 16)
+        {
+            switch (mode)
+            {
+            case PULLDOWN:
+                LPC_PINCON->PINMODE2 |= (3 << (bit*2));
+                break;
+            case PULLUP:
+                LPC_PINCON->PINMODE2 &= ~(3 << (bit*2));
+                break;
+            case PULLNONE:
+                LPC_PINCON->PINMODE2 |= (1 << (bit*2));
+                LPC_PINCON->PINMODE2 &= ~(1 << ((bit*2)+1));
+                break;
+            case KEEPER:
+                LPC_PINCON->PINMODE2 &= ~(1 << (bit*2));
+                LPC_PINCON->PINMODE2 |= (1 << ((bit*2)+1));
+                break;
+            }
+        }
+        else
+        {
+            switch (mode)
+            {
+            case PULLDOWN:
+                LPC_PINCON->PINMODE3 |= (3 << (2*(bit-16)));
+                break;
+            case PULLUP:
+                LPC_PINCON->PINMODE3 &= ~(3 << (2*(bit-16)));
+                break;
+            case PULLNONE:
+                LPC_PINCON->PINMODE3 |= (1 << (2*(bit-16)));
+                LPC_PINCON->PINMODE3 &= ~(1 << ((2*(bit-16))+1));
+                break;
+            case KEEPER:
+                LPC_PINCON->PINMODE3 &= ~(1 << (2*(bit-16)));
+                LPC_PINCON->PINMODE3 |= (1 << ((2*(bit-16))+1));
+                break;
+            }
+        }    
+    }
+    else if (port==2)
+    {
+        if(bit < 16)
+        {
+            switch (mode)
+            {
+            case PULLDOWN:
+                LPC_PINCON->PINMODE4 |= (3 << (bit*2));
+                break;
+            case PULLUP:
+                LPC_PINCON->PINMODE4 &= ~(3 << (bit*2));
+                break;
+            case PULLNONE:
+                LPC_PINCON->PINMODE4 |= (1 << (bit*2));
+                LPC_PINCON->PINMODE4 &= ~(1 << ((bit*2)+1));
+                break;
+            case KEEPER:
+                LPC_PINCON->PINMODE4 &= ~(1 << (bit*2));
+                LPC_PINCON->PINMODE4 |= (1 << ((bit*2)+1));
+                break;
+            }
+        }
+        else
+        {
+            switch (mode)
+            {
+            case PULLDOWN:
+                LPC_PINCON->PINMODE5 |= (3 << (2*(bit-16)));
+                break;
+            case PULLUP:
+                LPC_PINCON->PINMODE5 &= ~(3 << (2*(bit-16)));
+                break;
+            case PULLNONE:
+                LPC_PINCON->PINMODE5 |= (1 << (2*(bit-16)));
+                LPC_PINCON->PINMODE5 &= ~(1 << ((2*(bit-16))+1));
+                break;
+            case KEEPER:
+                LPC_PINCON->PINMODE5 &= ~(1 << (2*(bit-16)));
+                LPC_PINCON->PINMODE5 |= (1 << ((2*(bit-16))+1));
+                break;
+            }
+        }   
+    }
+    //TODO: check PULLNONE and KEEPER,... it is possible they are backwards
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/InOut.h	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,63 @@
+#ifndef __INOUT_H_
+#define __INOUT_H_
+
+#include "LPC17xx.h"
+
+//useful constants to define
+#define PULLUP 0
+#define PULLDOWN 1
+#define PULLNONE 2
+#define KEEPER 3
+#define OUTPUT 1
+#define INPUT 0
+#define LED1 1
+#define LED2 2
+#define LED3 3
+#define LED4 4
+#define NULL 0
+
+#define p5 5
+#define p6 6
+#define p7 7
+#define p8 8
+#define p9 9
+#define p10 10
+#define p11 11
+#define p12 12
+#define p13 13
+#define p14 14
+#define p15 15
+#define p16 16
+#define p17 17
+#define p18 18
+#define p19 19
+#define p20 20
+#define p21 21
+#define p22 22
+#define p23 23
+#define p24 24
+#define p25 25
+#define p26 26
+#define p27 27
+#define p28 28
+#define p29 29
+#define p30 30
+
+class InOut
+{
+public: // char type if value never goes above 256
+    char port; //the port number (ports 0, 1 or 2)
+    char bit; //the bit of the port
+    void write(bool); //bool because it can only be high or low
+    bool read(); //bool because it can only be high or low
+    InOut(char, bool); //contructor for pins (led or mbed pin #, and 1 for output or 0 for input)
+    InOut(char, char, bool); // port, bit and 1 for output / 0 for input. This is for the pins that the mbed doesn't use
+    void setDirection(bool); // the constructor calls this method, but we can call it too if we need to
+    void mode(char); // PULLUP, PULLDOWN, PULLNONE or KEEPER (char because really we are only using 2 bits)
+    InOut& operator=(bool); // so we can do led1 = 0; instead of led1.write(0); just like the mbed library does
+    operator bool(); // so we can do "led1" instead of "led1.read()" just like the mbed library does
+    void output(); //calls setDirection, to set bit to output
+    void input(); //calls setDirection, to set bit to input
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Serial.cpp	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,154 @@
+#include "Serial.h"
+
+void Serial::initUART0()
+{
+    int pclk;
+    unsigned long int Fdiv;
+
+    // PCLK_UART0 is being set to 1/4 of SystemCoreClock
+    pclk = SystemCoreClock / 4;     
+    
+    // Turn on power to UART0
+    LPC_SC->PCONP |=  (1 << 3);
+            
+    // Turn on UART0 peripheral clock
+    LPC_SC->PCLKSEL0 &= ~(3 << 6); // mask
+    LPC_SC->PCLKSEL0 |=  (0 << 6);         // PCLK_periph = CCLK/4 ,, 6 is pclk for uart0
+    
+    // Set PINSEL0 so that P0.2 = TXD0, P0.3 = RXD0
+    LPC_PINCON->PINSEL0 &= ~0xf0;
+    LPC_PINCON->PINSEL0 |= ((1 << 4) | (1 << 6));
+    
+    LPC_UART0->LCR = 0x83;          // 8 bits, no Parity, 1 Stop bit, DLAB=1
+    Fdiv = ( pclk / 16 ) / baudrate ;   // Set baud rate
+    LPC_UART0->DLM = Fdiv / 256;                                                        
+    LPC_UART0->DLL = Fdiv % 256;
+    LPC_UART0->LCR = 0x03;              // 8 bits, no Parity, 1 Stop bit DLAB = 0
+    LPC_UART0->FCR = 0x07;              // Enable and reset TX and RX FIFO
+}
+
+Serial::Serial()
+{
+    baudrate = 9600;
+    initUART0();
+}
+
+Serial::Serial(int br)
+{
+    baudrate = br;
+    initUART0();
+}
+
+void Serial::putc(char c)
+{
+    while( !(LPC_UART0->LSR & 0x20) );      // Block until tx empty
+    
+    LPC_UART0->THR = c;
+}
+
+char Serial::getc()
+{
+    char c;
+    while( !(LPC_UART0->LSR & 0x01) );  // wait until something received   
+    c = LPC_UART0->RBR; // Read Receiver buffer register
+    return c;
+}
+
+void Serial::printf(char* sendstring)
+{
+    int i = 0;
+    // loop through until reach string's zero terminator
+    while (sendstring[i] != '\0')
+    {
+            putc(sendstring[i]); // print each character
+            i++;
+    }
+}
+
+void Serial::printf(double number)
+{
+    int numberAsInt = number; //truncates right of decimal point
+    printf(numberAsInt);
+    putc('.');
+    int rightOfDecimal = (number-numberAsInt)*1000000000; //truncating smaller than 10^(-9)
+    printf(rightOfDecimal);
+}
+
+void Serial::printf(double number, int res)
+{
+    int numberAsInt = number; //truncates right of decimal point
+    printf(numberAsInt);
+    putc('.');
+    int rightOfDecimal = (number-numberAsInt)*res;
+    printf(rightOfDecimal);
+}
+
+void Serial::printf(int number)
+{
+    //we go from left to right
+    int numofdigits = 0;
+    int temp2 = number;
+    while(temp2 > 0)
+    {
+        numofdigits = numofdigits + 1;
+        temp2 = temp2 / 10;
+    } 
+    
+    while(numofdigits > 0)
+    {
+        int temp = numofdigits;
+        int position = 1;
+        while(temp > 1)
+        {
+            position = position * 10;
+            temp = temp - 1;
+        }
+        
+        int digit = (number / position) % 10;
+        
+        char character = tochar(digit);
+        putc(character);
+        numofdigits = numofdigits - 1; //
+    }    
+}
+
+// converts an individual digit into a character
+char Serial::tochar(int digit)
+{
+    int character = '0';
+    switch (digit)
+    {
+    case 0 :
+        character = '0';
+        break;
+    case 1 :
+        character = '1';
+        break;
+    case 2 :
+        character = '2';
+        break;
+    case 3 :
+        character = '3';
+        break;
+    case 4 :
+        character = '4';
+        break;
+    case 5 :
+        character = '5';
+        break;
+    case 6 :
+        character = '6';
+        break;
+    case 7 :
+        character = '7';
+        break;
+    case 8 :
+        character = '8';
+        break;
+    case 9 :
+        character = '9';
+        break;
+    }
+
+    return character;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Serial.h	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,24 @@
+#ifndef __SERIAL_H_
+#define __SERIAL_H_
+
+#include "LPC17xx.h"
+
+//This is really just UART0 which goes over USB to the PC
+class Serial
+{
+private:
+    int baudrate;
+    void initUART0();
+    char tochar(int);
+public:
+    Serial(); //defualt baudrate is 9600
+    Serial(int); //constructor with baudrate
+    void putc(char);
+    char getc();
+    void printf(char*);
+    void printf(int);
+    void printf(double);
+    void printf(double, int);
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Ticker.cpp	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,102 @@
+#include "Ticker.h"
+//This class uses Timer 2
+
+extern "C" void TIMER2_IRQHandler(void)
+{
+  if ( LPC_TIM2->IR & 0x1 )
+  {
+    LPC_TIM2->IR = 0x1;              /* clear interrupt flag */
+    for(char count = 0; count < Ticker::active_tickers; count++)
+    {
+        if((*(Ticker::tickers[count])).active)
+        {
+            if((*(Ticker::tickers[count])).remaining == 0)
+            {
+                //void (*func)(void) = (void (*)(void))((uint32_t)&isr);
+                //func();
+                (*(void (*)(void))((*(Ticker::tickers[count])).func))();
+    
+                if((*(Ticker::tickers[count])).timeout)
+                    (*(Ticker::tickers[count])).active = false;
+                else
+                    (*(Ticker::tickers[count])).remaining = (*(Ticker::tickers[count])).interval - 1; //set up for next interval
+            }
+            else
+            {
+                (*(Ticker::tickers[count])).remaining = (*(Ticker::tickers[count])).remaining - 1;
+            }       
+        }
+    }
+  }
+}
+
+// static data initialization  (only called once)
+bool Ticker::timer2initialized = false; 
+int Ticker::active_tickers = 0;
+int Ticker::MAX = 5;
+Ticker** Ticker::tickers = 0; //NULL POINTER
+
+void Ticker::initTimer2() 
+{
+    LPC_SC->PCLKSEL1 &= (3 << 12); //mask
+    LPC_SC->PCLKSEL1 |= (1 << 12); //sets it to 1*SystemCoreClock - table 42 (page 57 in user manual)
+
+    LPC_SC->PCONP |= (0x1<<22);     // turn on power for timer 2
+    LPC_TIM2->TCR = 0x02;           // reset timer
+    LPC_TIM2->PR  = (SystemCoreClock / 1000000); //microsecond steps
+    LPC_TIM2->MR0 = 100;            // 100 microsecond interval interrupts
+    LPC_TIM2->IR  = 0x3f;           // reset all interrrupts
+    LPC_TIM2->MCR = 0x03;           // reset timer on match and generate interrupt (MR0)
+    LPC_TIM2->TCR = 0x01;           // start timer
+    
+    NVIC_EnableIRQ(TIMER2_IRQn); // Enable the interrupt
+    
+    timer2initialized = true;
+}
+
+Ticker::Ticker()
+{
+    if(!timer2initialized)
+    {
+        initTimer2();
+        tickers = new Ticker*[MAX];
+    }
+    active = false;
+    timeout = false;
+}
+
+Ticker::Ticker(int maxsize)
+{
+    if(!timer2initialized)
+    {
+        initTimer2();
+        tickers = new Ticker*[maxsize];
+        MAX = maxsize;
+    }
+    active = false;
+    timeout = false;
+}
+
+void Ticker::attach(void (*funcaddr)(void), float secinterval)
+{
+
+    func = (uint32_t)funcaddr; //pointer to function address
+    interval = secinterval*10000;
+    remaining = secinterval*10000 - 1; // 100 microsecond resolution
+    tickers[active_tickers] = this;
+    active_tickers = active_tickers + 1;
+    active = true;
+}
+
+void Ticker::detach()
+{
+    active_tickers = active_tickers - 1;
+    tickers[active_tickers] = 0; //NULL pointer
+    active = false;
+}
+
+Ticker::~Ticker()
+{
+    if(active || timeout)
+        detach();   
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Ticker.h	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,58 @@
+#ifndef __TICKER_H_
+#define __TICKER_H_
+
+#include "LPC17xx.h"
+//#include "cmsis_nvic.h"
+//old way: NVIC_SetVector(TIMER2_IRQn, funcaddr); //tell it to run this function
+
+
+/**
+ * @author Jason Garner
+ *
+ * <b>Ticker</b> is an alternative implementation of the Mbed library <a href="/handbook/Ticker">Ticker</a> to save memory.
+ * The maximum number of Ticker instances is fully customizable. 
+ *
+ */
+class Ticker
+{
+    void initTimer2(); // the constructor initializes the hardware timer, if it wasn't already initialized
+public:
+    static bool timer2initialized; //stores whether the timer has been initialized
+    static Ticker** tickers; //array of pointers to ticker instances
+    uint32_t func; //function that NVIC will call on interrupts
+    uint32_t interval; // unit interval to execute func (unit = 100 microseconds)
+    uint32_t remaining; // units remaning until executing func (unit = 100 microseconds)
+    static int active_tickers; //how many instances of this class we have that are attached. (NVIC needs this)
+    static int MAX; // max size of Ticker* array
+    bool active; // whether or not the instance is an active Ticker 
+    bool timeout; // if set to true, this is effectively a Timeout object now. (it detaches after the next function call)
+     /**
+     * Regular constructor: the default internal array size is 5.
+     */  
+    Ticker();
+
+     /**
+     * Custom constructor: initializes the object with the specified parameter.
+     *
+     * @param max Maximum instances of Ticker objects allowed. (sets internal array size of Ticker* to instances)
+     */  
+    Ticker(int);
+    
+    ~Ticker(); //DESTRUCTOR   
+    
+     /**
+     * Attach a function to be called by the Ticker, specifiying the interval in seconds. 
+     * The timer is a 32bit 100 microsecond Timer, so the smallest time is 100 microseconds and the largest time is about 59 hours. 
+     *
+     * @param fptr pointer to the function to be called 
+     * @param t The time in seconds in between function calls.
+     */  
+    void attach(void (*fptr)(void), float t); //address of function to call, and interval to call it
+    
+     /**
+     * Detaches the function from the Ticker. The function will no longer be called, and a new one can now be attached.
+     */  
+    void detach(); //removes address from ticker array
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Timeout.cpp	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,18 @@
+#include "Timeout.h"
+
+Timeout::Timeout()
+{
+    ticker.timeout = true;
+}
+
+void Timeout::attach(void (*func)(void), float t)
+{
+    ticker.attach(func, t);
+}
+
+// still needs detaching before attaching another timeout
+// because it still exists in the tickers array, it is just not active, so the function isn't gonna be called
+void Timeout::detach()
+{
+    ticker.detach();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Timeout.h	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,17 @@
+#ifndef __TIMEOUT_H_
+#define __TIMEOUT_H_
+
+#include "LPC17xx.h"
+#include "Ticker.h"
+
+// this class reuses my Ticker class, so that timer 3 can be used for when I code the InterruptIn class
+class Timeout
+{
+    Ticker ticker;
+public:
+    Timeout();
+    void attach(void (*fptr)(void), float);
+    void detach();
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Timer.cpp	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,111 @@
+#include "Timer.h"
+//This class uses Timer 1
+
+// static data initialization  (only called once)
+bool Timer::timer1initialized = false; 
+int Timer::resolution = 1000000; //default: microseconds accuracy
+
+void Timer::initTimer1(int res) 
+{
+    uint8_t pclk;
+    uint32_t pclkdiv = (LPC_SC->PCLKSEL0 >> 4) & 0x03; //PCLK for Timer 1 (page 56)
+
+    switch ( pclkdiv ) // table 42 (page 57 in user manual)
+    {
+      case 0x00:
+      default:
+            pclk = 4;
+            break;
+      case 0x01:
+            pclk = 1;
+            break;
+      case 0x02:
+            pclk = 2;
+            break;
+      case 0x03:
+            pclk = 8;
+            break;
+    }
+
+    LPC_TIM1->TCR = 0x02;           // reset timer
+    LPC_TIM1->PR  = (SystemCoreClock / (pclk * res)); //default: microsecond steps
+    LPC_TIM1->MR0 = 2147483647;             // highest number a 32bit signed int can store (for us ~ 35.79 minutes, or, for ms ~ 596.52 hours )
+    LPC_TIM1->IR  = 0xff;           // reset all interrrupts
+    LPC_TIM1->MCR = 0x02;           // reset timer on match
+    LPC_TIM1->TCR = 0x01;           // start timer
+
+    // The timer simply goes on forever! It just resets itself when it hits the max number for TC
+    timer1initialized = true;
+    resolution = res;
+}
+
+Timer::Timer()
+{        
+    if(!timer1initialized)
+    {
+        initTimer1(resolution); //default resolution
+    }
+    
+    starttime = 0;
+    stoptime = 0;
+    running = false;
+}
+
+//for when we want to allow lower counting resolution, eg. milliseconds
+//so we can count longer than the 35 minutes with microsecond resolution
+Timer::Timer(int res) // millisecond, res = 1000
+{   
+    if(!timer1initialized)
+    {
+        initTimer1(res); //custom resolution
+    }
+    
+    starttime = 0;
+    stoptime = 0;
+    running = false;
+}
+
+void Timer::start()
+{
+    starttime = LPC_TIM1->TC;
+    stoptime = 0; //clear previous stoptime
+    running = true;
+}
+
+void Timer::stop()
+{
+   stoptime = LPC_TIM1->TC;
+   running = false;
+}
+
+void Timer::reset()
+{
+    if(running)
+    {
+        starttime = LPC_TIM1->TC;
+    }
+    else
+    {
+        starttime = 0;
+    }
+    
+    stoptime = 0;
+}
+
+float Timer::read()
+{
+    if(running)
+    {    
+        int currenttime = LPC_TIM1->TC;
+        return (currenttime - starttime) / (resolution*1.0);
+    }
+    else // compare startime and stoptime
+    {
+        return (stoptime - starttime) / (resolution*1.0);
+    }
+}
+
+Timer::operator float()
+{
+    return read();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Timer.h	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,24 @@
+#ifndef __TIMER_H_
+#define __TIMER_H_
+
+#include "LPC17xx.h"
+
+class Timer
+{
+    void initTimer1(int); // the constructor initializes the hardware timer, if it wasn't already initialized
+    static bool timer1initialized; //stores whether the timer has been initialized
+    static int resolution;
+    int starttime;
+    int stoptime;
+    bool running;
+public:
+    Timer(); //default of microsecond resolution
+    Timer(int); //custom resolution.. eg. 1000 = millisecond resolution
+    void start();
+    void stop();
+    void reset();
+    float read();
+    operator float(); //read shortcut
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/functions.cpp	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,39 @@
+//this file is for all the global functions that I need to use
+//but are here, so they are not cluttering up main.cpp
+#include "functions.h"
+
+//this uses Timer 0, but we could just as easily change it to Timer 1, 2 or 3
+void wait(float time) //seconds
+{
+    uint32_t us = time * 1000000; //microseconds
+
+    uint8_t pclk;
+    uint32_t pclkdiv = (LPC_SC->PCLKSEL0 >> 2) & 0x03;
+
+    switch ( pclkdiv ) // table 42 (page 57 in user manual)
+    {
+      case 0x00:
+      default:
+            pclk = 4;
+            break;
+      case 0x01:
+            pclk = 1;
+            break;
+      case 0x02:
+            pclk = 2;
+            break;
+      case 0x03:
+            pclk = 8;
+            break;
+    }
+
+    LPC_TIM0->TCR = 0x02;           /* reset timer */
+    LPC_TIM0->PR  = (SystemCoreClock / (pclk * 1000000));
+    LPC_TIM0->MR0 = us;             /* enter delay time */
+    LPC_TIM0->IR  = 0xff;           /* reset all interrrupts */
+    LPC_TIM0->MCR = 0x04;           /* stop timer on match */
+    LPC_TIM0->TCR = 0x01;           /* start timer */
+
+    /* wait until delay time has elapsed */
+    while (LPC_TIM0->TCR & 0x01);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/functions.h	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,8 @@
+#ifndef __FUNCTIONS_CPP_
+#define __FUNCTIONS_CPP_
+
+#include "LPC17xx.h"
+
+void wait(float); //wait a specified time in seconds (accurate down to a microsecond)
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/registers.h	Thu Jan 03 04:25:08 2013 +0000
@@ -0,0 +1,15 @@
+#ifndef __REGISTERS_H_
+#define __REGISTERS_H_
+
+//consoladates include statements for things i've written
+//that use the internal registers of the NXP LPC1768
+#include "DigitalIn.h"
+#include "DigitalOut.h"
+#include "Serial.h"
+#include "functions.h"
+#include "Timer.h"
+#include "Ticker.h"
+#include "Timeout.h"
+//TODO : MORE!!!!!!
+
+#endif
\ No newline at end of file