Igor Skochinsky
/
FastIO
Fast GPIO using C++ templates. Now with port I/O.
main.cpp@0:f1e54c45ccaf, 2010-03-12 (annotated)
- Committer:
- igorsk
- Date:
- Fri Mar 12 10:12:32 2010 +0000
- Revision:
- 0:f1e54c45ccaf
- Child:
- 1:8064f8b8cf82
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
igorsk | 0:f1e54c45ccaf | 1 | #include "mbed.h" |
igorsk | 0:f1e54c45ccaf | 2 | // Super-fast DigitalOut-like class for mbed |
igorsk | 0:f1e54c45ccaf | 3 | // by Igor Skochinsky |
igorsk | 0:f1e54c45ccaf | 4 | |
igorsk | 0:f1e54c45ccaf | 5 | // usage: FastOut<LED2> led2; |
igorsk | 0:f1e54c45ccaf | 6 | // then use the same assignment operators as with DigitalOut |
igorsk | 0:f1e54c45ccaf | 7 | template <PinName pin> class FastOut |
igorsk | 0:f1e54c45ccaf | 8 | { |
igorsk | 0:f1e54c45ccaf | 9 | // pin = LPC_GPIO0_BASE + port * 32 + bit |
igorsk | 0:f1e54c45ccaf | 10 | // port = (pin - LPC_GPIO0_BASE) / 32 |
igorsk | 0:f1e54c45ccaf | 11 | // bit = (pin - LPC_GPIO0_BASE) % 32 |
igorsk | 0:f1e54c45ccaf | 12 | |
igorsk | 0:f1e54c45ccaf | 13 | // helper function to calculate the GPIO port definition for the pin |
igorsk | 0:f1e54c45ccaf | 14 | // we rely on the fact that port structs are 0x20 bytes apart |
igorsk | 0:f1e54c45ccaf | 15 | inline LPC_GPIO_TypeDef* portdef() { return (LPC_GPIO_TypeDef*)(LPC_GPIO0_BASE + ((pin - P0_0)/32)*0x20); }; |
igorsk | 0:f1e54c45ccaf | 16 | |
igorsk | 0:f1e54c45ccaf | 17 | // helper function to calculate the mask for the pin's bit in the port |
igorsk | 0:f1e54c45ccaf | 18 | inline uint32_t mask() { return 1UL<<((pin - LPC_GPIO0_BASE) % 32); }; |
igorsk | 0:f1e54c45ccaf | 19 | |
igorsk | 0:f1e54c45ccaf | 20 | public: |
igorsk | 0:f1e54c45ccaf | 21 | FastOut() |
igorsk | 0:f1e54c45ccaf | 22 | { |
igorsk | 0:f1e54c45ccaf | 23 | // set FIODIR bit to 1 (output) |
igorsk | 0:f1e54c45ccaf | 24 | portdef()->FIODIR |= mask(); |
igorsk | 0:f1e54c45ccaf | 25 | } |
igorsk | 0:f1e54c45ccaf | 26 | void write(int value) |
igorsk | 0:f1e54c45ccaf | 27 | { |
igorsk | 0:f1e54c45ccaf | 28 | if ( value ) |
igorsk | 0:f1e54c45ccaf | 29 | portdef()->FIOSET = mask(); |
igorsk | 0:f1e54c45ccaf | 30 | else |
igorsk | 0:f1e54c45ccaf | 31 | portdef()->FIOCLR = mask(); |
igorsk | 0:f1e54c45ccaf | 32 | } |
igorsk | 0:f1e54c45ccaf | 33 | int read() |
igorsk | 0:f1e54c45ccaf | 34 | { |
igorsk | 0:f1e54c45ccaf | 35 | return (portdef()->FIOPIN) & mask() != 0; |
igorsk | 0:f1e54c45ccaf | 36 | } |
igorsk | 0:f1e54c45ccaf | 37 | FastOut& operator= (int value) { write(value); return *this; }; |
igorsk | 0:f1e54c45ccaf | 38 | FastOut& operator= (FastOut& rhs) { return write(rhs.read()); }; |
igorsk | 0:f1e54c45ccaf | 39 | operator int() { return read(); }; |
igorsk | 0:f1e54c45ccaf | 40 | }; |
igorsk | 0:f1e54c45ccaf | 41 | |
igorsk | 0:f1e54c45ccaf | 42 | DigitalOut led1(LED1); |
igorsk | 0:f1e54c45ccaf | 43 | FastOut<LED2> led2; |
igorsk | 0:f1e54c45ccaf | 44 | |
igorsk | 0:f1e54c45ccaf | 45 | Timer t; |
igorsk | 0:f1e54c45ccaf | 46 | #define LOOPS 100000000 |
igorsk | 0:f1e54c45ccaf | 47 | int main() { |
igorsk | 0:f1e54c45ccaf | 48 | int value = 0; |
igorsk | 0:f1e54c45ccaf | 49 | int count = LOOPS; |
igorsk | 0:f1e54c45ccaf | 50 | t.start(); |
igorsk | 0:f1e54c45ccaf | 51 | while ( count -- ) |
igorsk | 0:f1e54c45ccaf | 52 | { |
igorsk | 0:f1e54c45ccaf | 53 | led1.write(value); |
igorsk | 0:f1e54c45ccaf | 54 | value = 1-value; |
igorsk | 0:f1e54c45ccaf | 55 | } |
igorsk | 0:f1e54c45ccaf | 56 | t.stop(); |
igorsk | 0:f1e54c45ccaf | 57 | printf("DigitalOut: %f seconds (%d ns per iteration).\n", t.read(), t.read_us()/(LOOPS/1000)); |
igorsk | 0:f1e54c45ccaf | 58 | count = LOOPS; |
igorsk | 0:f1e54c45ccaf | 59 | t.reset(); |
igorsk | 0:f1e54c45ccaf | 60 | t.start(); |
igorsk | 0:f1e54c45ccaf | 61 | while ( count -- ) |
igorsk | 0:f1e54c45ccaf | 62 | { |
igorsk | 0:f1e54c45ccaf | 63 | led2 = value; |
igorsk | 0:f1e54c45ccaf | 64 | value = 1-value; |
igorsk | 0:f1e54c45ccaf | 65 | } |
igorsk | 0:f1e54c45ccaf | 66 | t.stop(); |
igorsk | 0:f1e54c45ccaf | 67 | printf("FastOut: %f seconds (%d ns per iteration).\n", t.read(), t.read_us()/(LOOPS/1000)); |
igorsk | 0:f1e54c45ccaf | 68 | } |