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.

InOut.cpp

Committer:
elevatorguy
Date:
2013-01-03
Revision:
0:d2d9baa1a6d8

File content as of revision 0:d2d9baa1a6d8:

#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
}