Andy K / Lib17_Core

include/Lib17_DIO.h

Committer:
AjK
Date:
2011-04-11
Revision:
0:127224866798
Child:
1:2f99edb5545c

File content as of revision 0:127224866798:

/****************************************************************************
 * Product: LIB17 Open Source Library
 *
 *                    Steller Technologies Limited
 *                    ----------------------------
 *
 * Copyright (C) 2002-2011 Steller Technologies Limited. All rights reserved.
 *
 * This software may be distributed and modified under the terms of the GNU
 * General Public License version 2 (GPL) as published by the Free Software
 * Foundation and appearing in the file GPL.TXT included in the packaging of
 * this file. Please note that GPL Section 2[b] requires that all works based
 * on this software must also be made publicly available under the terms of
 * the GPL ("Copyleft").
 *
 * Alternatively, this software may be distributed and modified under the
 * terms of Steller Technologies Limited commercial licenses, which expressly
 * supersede the GPL and are specifically designed for licensees interested in
 * retaining the proprietary status of their code.
 *
 ***************************************************************************/

#ifndef AJK_Lib17_DIO_H
#define AJK_Lib17_DIO_H

#include "Lib17_Mbed.h"
#include "Lib17_IOmacros.h"

namespace AjK {

class Lib17_DIO {
public:
    enum Direction {
          Out = 0
        , In
    };

protected:
    PinName pin;
    uint32_t mask;
    uint32_t fiodir;
    uint32_t fiomask;
    uint32_t fiopin;
    uint32_t fioset;
    uint32_t fioclr;

    inline void setpin(PinName p)  { pin     = p; }
    inline void setmask(PinName p) { mask    = (uint32_t)(1UL << ((uint32_t)p & 0x1F)); }
    inline void setDir(PinName p)  { fiodir  = (uint32_t)(p & ~0x1F) + 0x00; }
    inline void setMask(PinName p) { fiomask = (uint32_t)(p & ~0x1F) + 0x10; }
    inline void setPin(PinName p)  { fiopin  = (uint32_t)(p & ~0x1F) + 0x14; }
    inline void setSet(PinName p)  { fioset  = (uint32_t)(p & ~0x1F) + 0x18; }
    inline void setClr(PinName p)  { fioclr  = (uint32_t)(p & ~0x1F) + 0x1C; }

    inline void pinUp() { *((volatile uint32_t *)fioset) = mask; }
    inline void pinDn() { *((volatile uint32_t *)fioclr) = mask; }
    inline uint32_t pinIs() { return *((volatile uint32_t *)(fiopin)) & mask; }

public:

    Lib17_DIO(PinName p, Direction d = Out, PinMode m = PullDown) { init(p, d, m); };

    void write(int i)     { if (i!=0) { pinUp(); } else { pinDn(); } }
    int  read(void)       { return pinIs() ? 1 : 0; };
    void output(void)    { *((volatile uint32_t *)fiodir) |=  mask; }
    void input(void)    { *((volatile uint32_t *)fiodir) &= ~mask; }

    PinName getPin(void) { return pin; }
    int getDirection(void) { return *((volatile uint32_t *)fiomask) & mask ? 1 : 0; }

    operator int() { return read(); }
    Lib17_DIO& operator= (int value)  { write(value); return *this; }
    Lib17_DIO& operator= (Lib17_DIO& rhs) { write(rhs.read()); return *this; }

    uint32_t getMask(void)    { return mask;    }
    uint32_t getFiodir(void)  { return fiodir;  }
    uint32_t getFiomask(void) { return fiomask; }
    uint32_t getFiopin(void)  { return fiopin;  }
    uint32_t getFioset(void)  { return fioset;  }
    uint32_t getFioclr(void)  { return fioclr;  }


protected:
    void init(PinName p, Direction d, PinMode m)
    {
        // We rely on the fact that by default the LPC1768
        // sets all pins to be GPIO. The user will change
        // that if they need to. So we don't bother trying
        // to setup PINSELx
    
        // psel(); // Not used, see above.
    
        setpin(p);
        setmask(p);
        setDir(p);
        setMask(p);
        setPin(p);
        setSet(p);
        setClr(p);
    
        if (d == Out) output();
        else mode( m );
    }

protected:
    void psel(void)
    {
        uint32_t ppsel, pumask;
    
        if (pin >= P0_0 && pin <= P0_15)         ppsel = (uint32_t)(&LPC_PINCON->PINSEL0);
        else if (pin >= P0_16 && pin <= P0_31)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL1);
        else if (pin >= P1_0 && pin <= P1_15)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL2);
        else if (pin >= P1_16 && pin <= P1_31)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL3);
        else if (pin >= P2_0 && pin <= P2_15)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL4);
        else if (pin >= P3_16 && pin <= P3_31)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL7);
        else if (pin >= P4_16 && pin <= P4_31)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL9);
        else return;
    
        pumask = ~(3UL << ((pin & 0x1F)>>1));
        *((volatile uint32_t *)ppsel) &= pumask;
    }

public:
    void mode(PinMode m) 
    {
        uint32_t ppmod, pumask;
    
        if (m == OpenDrain) {
            openDrain(1);
        }
        else {
            if (pin >= P0_0 && pin <= P0_15) {
                ppmod = (uint32_t)(&LPC_PINCON->PINMODE0);
                pumask = ((m & 0x3) << ( ((pin & 0x1F)-0)*2) );
            }
            else if (pin >= P0_16 && pin <= P0_31) {
                ppmod = (uint32_t)(&LPC_PINCON->PINMODE1);
                pumask = ((m & 0x3) << ( ((pin & 0x1F)-16)*2) );
            }
            else if (pin >= P1_0 && pin <= P1_15) {
                ppmod = (uint32_t)(&LPC_PINCON->PINMODE2);
                pumask = ((m & 0x3) << ( ((pin & 0x1F)-0)*2) );
            }
            else if (pin >= P1_16 && pin <= P1_31) {
                 ppmod = (uint32_t)(&LPC_PINCON->PINMODE3);
                 pumask = ((m & 0x3) << ( ((pin & 0x1F)-16)*2) );
            }
            else if (pin >= P2_0 && pin <= P2_15) {
                ppmod = (uint32_t)(&LPC_PINCON->PINMODE4);
                pumask = ((m & 0x3) << ( ((pin & 0x1F)-0)*2) );
            }
            else if (pin >= P3_16 && pin <= P3_31) {
                ppmod = (uint32_t)(&LPC_PINCON->PINMODE7);
                pumask = ((m & 0x3) << ( ((pin & 0x1F)-16)*2) );
            }
            else if (pin >= P4_16 && pin <= P4_31) {
                ppmod = (uint32_t)(&LPC_PINCON->PINMODE9);
                pumask = ((m & 0x3) << ( ((pin & 0x1F)-16)*2) );
            }
            else return;
    
            *((volatile uint32_t *)ppmod) |= pumask;
        }
    }

public:
    void openDrain(int i = 1) 
    {
        if (pin >= P0_0 && pin <= P0_31)           { if (i) LPC_PINCON->PINMODE_OD0 |= mask; else LPC_PINCON->PINMODE_OD0 &= ~mask; }
        else if (pin >= P1_0 && pin <= P1_31)      { if (i) LPC_PINCON->PINMODE_OD1 |= mask; else LPC_PINCON->PINMODE_OD1 &= ~mask; }
        else if (pin >= P2_0 && pin <= P2_31)      { if (i) LPC_PINCON->PINMODE_OD2 |= mask; else LPC_PINCON->PINMODE_OD2 &= ~mask; }
        else if (pin >= P3_16 && pin <= P3_31)     { if (i) LPC_PINCON->PINMODE_OD3 |= mask; else LPC_PINCON->PINMODE_OD3 &= ~mask; }
        else if (pin >= P4_16 && pin <= P4_31)     { if (i) LPC_PINCON->PINMODE_OD4 |= mask; else LPC_PINCON->PINMODE_OD4 &= ~mask; }
    }

};

}; /* namespace AjK ends. */

using namespace AjK;

#endif /* AJK_Lib17_DIO_H */