Fast GPIO using C++ templates. Now with port I/O.

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
igorsk
Date:
Sat May 22 23:31:39 2010 +0000
Parent:
2:9c4a8c01862c
Child:
4:b8e40f2a0aac
Commit message:

Changed in this revision

FastIO.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/FastIO.h	Sat May 22 23:13:55 2010 +0000
+++ b/FastIO.h	Sat May 22 23:31:39 2010 +0000
@@ -6,6 +6,18 @@
 // Super-fast DigitalOut-like class for mbed
 //   by Igor Skochinsky
 
+// includes FastOut, FastPortOut and MaskedPortOut classes
+// usage:
+//   FastOut<LED2> led2;
+//   FastPortOut<Port0, LED_MASK> ledport2;
+//   MaskedPortOut<Port0, LED_MASK> ledport3;
+//   led2 = 1;
+//   ledport2 = LED_MASK;
+//   ledport3 = LED_MASK;
+// MaskedPortOut works the same way as FastPortOut, but it pre-sets the pin mask so that write can be done in one operation
+// this makes things faster but you can't control other pins of the port, even with other classes
+
+
 // pin definitions in PinNames.h start from LPC_GPIO0_BASE for P0_0 and there are 32 pins to a port (0 to 31)
 // Thus:
 // pin = LPC_GPIO0_BASE + port * 32 + bit
@@ -60,7 +72,7 @@
 #define PINSELREG(pin)  (*(volatile uint32_t*)(LPC_PINCON_BASE + 4*(((pin) - P0_0)/16)))
 #define PINSELMASK(pin, v) (v << (((pin - P0_0)%16)*2) )
 
-// usage: FastPortOut<0> led2;
+// usage: FastPortOut<Port0, mask> led2;
 // then use the same assignment operators as with DigitalOut
 template <enum PortName port, uint32_t mask = 0xFFFFFFFF> class FastPortOut
 {
@@ -95,4 +107,40 @@
     operator int() { return read(); };
 };
 
+// usage: MaskedPortOut<Port0, mask> led2;
+// then use the same assignment operators as with DigitalOut
+template <enum PortName port, uint32_t mask = 0xFFFFFFFF> class MaskedPortOut
+{
+public:
+    MaskedPortOut()
+    {
+        // init pins selected by the mask
+        uint32_t pin = LPC_GPIO0_BASE + port * 32;
+        for ( uint32_t pinmask = mask; pinmask !=0; pinmask >>= 1 )
+        {
+            if ( pinmask & 1 )
+            {
+                // set PINSEL bits to 0b00 (GPIO)
+                PINSELREG(pin) &= ~PINSELMASK(pin, 3);
+                // set FIODIR bit to 1 (output)
+                PORTDEF(pin)->FIODIR |= PINMASK(pin);
+            }
+            pin++;
+        }
+        // set mask
+        PORTDEFPORT(port)->FIOMASK = mask;
+    }
+    void write(int value)
+    {
+        PORTDEFPORT(port)->FIOPIN = value;
+    } 
+    int read()
+    {
+        return PORTDEFPORT(port)->FIOPIN;
+    }
+    MaskedPortOut& operator= (int value) { write(value); return *this; };
+    MaskedPortOut& operator= (MaskedPortOut& rhs) { return write(rhs.read()); };
+    operator int() { return read(); };
+};
+
 #endif
\ No newline at end of file
--- a/main.cpp	Sat May 22 23:13:55 2010 +0000
+++ b/main.cpp	Sat May 22 23:31:39 2010 +0000
@@ -8,6 +8,7 @@
 FastOut<LED2> led2;
 PortOut ledport(Port0, LED_MASK);
 FastPortOut<Port0, LED_MASK> ledport2;
+MaskedPortOut<Port0, LED_MASK> ledport3;
 
 Timer t;
 #define LOOPS 100000000
@@ -57,4 +58,16 @@
     }
     t.stop();
     printf("FastPortOut: %f seconds (%d ns per iteration).\n", t.read(), t.read_us()/(LOOPS/1000));
+
+    count = LOOPS;
+    t.reset();
+    t.start();
+    value = LED_MASK;
+    while ( count -- )
+    {
+        ledport3 = value;
+        value ^= LED_MASK;
+    }
+    t.stop();
+    printf("MaskedPortOut: %f seconds (%d ns per iteration).\n", t.read(), t.read_us()/(LOOPS/1000));
 }