Andy K / Lib17_Core
Revision:
0:127224866798
Child:
1:2f99edb5545c
diff -r 000000000000 -r 127224866798 include/Lib17_DIO.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/Lib17_DIO.h	Mon Apr 11 15:05:27 2011 +0000
@@ -0,0 +1,182 @@
+/****************************************************************************
+ * 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 */