Alex Whittemore
/
BURTDAQ
Program to run data acquisition and control for BU Rocket Team's MKII hybrid rocket motor
FastIO.h@0:7fd45d2b5926, 2012-04-09 (annotated)
- Committer:
- alexwhittemore
- Date:
- Mon Apr 09 16:39:50 2012 +0000
- Revision:
- 0:7fd45d2b5926
For some reason, this thing wont run serial interrupts and threads simultaneously without locking up.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
alexwhittemore | 0:7fd45d2b5926 | 1 | #ifndef __FAST_IO_H |
alexwhittemore | 0:7fd45d2b5926 | 2 | #define __FAST_IO_H |
alexwhittemore | 0:7fd45d2b5926 | 3 | |
alexwhittemore | 0:7fd45d2b5926 | 4 | #include "mbed.h" |
alexwhittemore | 0:7fd45d2b5926 | 5 | |
alexwhittemore | 0:7fd45d2b5926 | 6 | // Super-fast DigitalOut-like class for mbed |
alexwhittemore | 0:7fd45d2b5926 | 7 | // by Igor Skochinsky |
alexwhittemore | 0:7fd45d2b5926 | 8 | |
alexwhittemore | 0:7fd45d2b5926 | 9 | // includes FastOut, FastPortOut and MaskedPortOut classes |
alexwhittemore | 0:7fd45d2b5926 | 10 | // usage: |
alexwhittemore | 0:7fd45d2b5926 | 11 | // FastOut<LED2> led2; |
alexwhittemore | 0:7fd45d2b5926 | 12 | // FastPortOut<Port0, LED_MASK> ledport2; |
alexwhittemore | 0:7fd45d2b5926 | 13 | // MaskedPortOut<Port0, LED_MASK> ledport3; |
alexwhittemore | 0:7fd45d2b5926 | 14 | // led2 = 1; |
alexwhittemore | 0:7fd45d2b5926 | 15 | // ledport2 = LED_MASK; |
alexwhittemore | 0:7fd45d2b5926 | 16 | // ledport3 = LED_MASK; |
alexwhittemore | 0:7fd45d2b5926 | 17 | // MaskedPortOut works the same way as FastPortOut, but it pre-sets the pin mask so that write can be done in one operation |
alexwhittemore | 0:7fd45d2b5926 | 18 | // this makes things faster but you can't control other pins of the port, even with other classes |
alexwhittemore | 0:7fd45d2b5926 | 19 | |
alexwhittemore | 0:7fd45d2b5926 | 20 | |
alexwhittemore | 0:7fd45d2b5926 | 21 | // pin definitions in PinNames.h start from LPC_GPIO0_BASE for P0_0 and there are 32 pins to a port (0 to 31) |
alexwhittemore | 0:7fd45d2b5926 | 22 | // Thus: |
alexwhittemore | 0:7fd45d2b5926 | 23 | // pin = LPC_GPIO0_BASE + port * 32 + bit |
alexwhittemore | 0:7fd45d2b5926 | 24 | // port = (pin - LPC_GPIO0_BASE) / 32 |
alexwhittemore | 0:7fd45d2b5926 | 25 | // bit = (pin - LPC_GPIO0_BASE) % 32 |
alexwhittemore | 0:7fd45d2b5926 | 26 | |
alexwhittemore | 0:7fd45d2b5926 | 27 | #define PORTNO(pin) (((pin) - P0_0)/32) |
alexwhittemore | 0:7fd45d2b5926 | 28 | #define BITNO(pin) (((pin) - P0_0)%32) |
alexwhittemore | 0:7fd45d2b5926 | 29 | |
alexwhittemore | 0:7fd45d2b5926 | 30 | // calculate the GPIO port definition for the pin |
alexwhittemore | 0:7fd45d2b5926 | 31 | // we rely on the fact that port structs are 0x20 bytes apart |
alexwhittemore | 0:7fd45d2b5926 | 32 | #define PORTDEF(pin) ((LPC_GPIO_TypeDef*)(LPC_GPIO0_BASE + PORTNO(pin)*0x20)) |
alexwhittemore | 0:7fd45d2b5926 | 33 | |
alexwhittemore | 0:7fd45d2b5926 | 34 | #define PORTDEFPORT(port) ((LPC_GPIO_TypeDef*)(LPC_GPIO0_BASE + port*0x20)) |
alexwhittemore | 0:7fd45d2b5926 | 35 | |
alexwhittemore | 0:7fd45d2b5926 | 36 | // calculate the mask for the pin's bit in the port |
alexwhittemore | 0:7fd45d2b5926 | 37 | #define PINMASK(pin) (1UL << BITNO(pin)) |
alexwhittemore | 0:7fd45d2b5926 | 38 | |
alexwhittemore | 0:7fd45d2b5926 | 39 | // each port takes two PINSEL registers (8 bytes or 64 bits) |
alexwhittemore | 0:7fd45d2b5926 | 40 | // so there are 16 pins per PINSEL |
alexwhittemore | 0:7fd45d2b5926 | 41 | #define PINSELREG(pin) (*(volatile uint32_t*)(LPC_PINCON_BASE + 4*(((pin) - P0_0)/16))) |
alexwhittemore | 0:7fd45d2b5926 | 42 | #define PINSELMASK(pin, v) (v << (((pin - P0_0)%16)*2) ) |
alexwhittemore | 0:7fd45d2b5926 | 43 | |
alexwhittemore | 0:7fd45d2b5926 | 44 | // usage: FastOut<LED2> led2; |
alexwhittemore | 0:7fd45d2b5926 | 45 | // then use the same assignment operators as with DigitalOut |
alexwhittemore | 0:7fd45d2b5926 | 46 | template <PinName pin> class FastOut |
alexwhittemore | 0:7fd45d2b5926 | 47 | { |
alexwhittemore | 0:7fd45d2b5926 | 48 | public: |
alexwhittemore | 0:7fd45d2b5926 | 49 | FastOut() |
alexwhittemore | 0:7fd45d2b5926 | 50 | { |
alexwhittemore | 0:7fd45d2b5926 | 51 | // set PINSEL bits to 0b00 (GPIO) |
alexwhittemore | 0:7fd45d2b5926 | 52 | PINSELREG(pin) &= ~PINSELMASK(pin, 3); |
alexwhittemore | 0:7fd45d2b5926 | 53 | // set FIODIR bit to 1 (output) |
alexwhittemore | 0:7fd45d2b5926 | 54 | PORTDEF(pin)->FIODIR |= PINMASK(pin); |
alexwhittemore | 0:7fd45d2b5926 | 55 | } |
alexwhittemore | 0:7fd45d2b5926 | 56 | void write(int value) |
alexwhittemore | 0:7fd45d2b5926 | 57 | { |
alexwhittemore | 0:7fd45d2b5926 | 58 | if ( value ) |
alexwhittemore | 0:7fd45d2b5926 | 59 | PORTDEF(pin)->FIOSET = PINMASK(pin); |
alexwhittemore | 0:7fd45d2b5926 | 60 | else |
alexwhittemore | 0:7fd45d2b5926 | 61 | PORTDEF(pin)->FIOCLR = PINMASK(pin); |
alexwhittemore | 0:7fd45d2b5926 | 62 | } |
alexwhittemore | 0:7fd45d2b5926 | 63 | int read() |
alexwhittemore | 0:7fd45d2b5926 | 64 | { |
alexwhittemore | 0:7fd45d2b5926 | 65 | return PORTDEF(pin)->FIOPIN & PINMASK(pin) != 0; |
alexwhittemore | 0:7fd45d2b5926 | 66 | } |
alexwhittemore | 0:7fd45d2b5926 | 67 | FastOut& operator= (int value) { write(value); return *this; }; |
alexwhittemore | 0:7fd45d2b5926 | 68 | FastOut& operator= (FastOut& rhs) { return write(rhs.read()); }; |
alexwhittemore | 0:7fd45d2b5926 | 69 | operator int() { return read(); }; |
alexwhittemore | 0:7fd45d2b5926 | 70 | }; |
alexwhittemore | 0:7fd45d2b5926 | 71 | |
alexwhittemore | 0:7fd45d2b5926 | 72 | #define PINSELREG(pin) (*(volatile uint32_t*)(LPC_PINCON_BASE + 4*(((pin) - P0_0)/16))) |
alexwhittemore | 0:7fd45d2b5926 | 73 | #define PINSELMASK(pin, v) (v << (((pin - P0_0)%16)*2) ) |
alexwhittemore | 0:7fd45d2b5926 | 74 | |
alexwhittemore | 0:7fd45d2b5926 | 75 | // usage: FastPortOut<Port0, mask> led2; |
alexwhittemore | 0:7fd45d2b5926 | 76 | // then use the same assignment operators as with DigitalOut |
alexwhittemore | 0:7fd45d2b5926 | 77 | template <enum PortName port, uint32_t mask = 0xFFFFFFFF> class FastPortOut |
alexwhittemore | 0:7fd45d2b5926 | 78 | { |
alexwhittemore | 0:7fd45d2b5926 | 79 | public: |
alexwhittemore | 0:7fd45d2b5926 | 80 | FastPortOut() |
alexwhittemore | 0:7fd45d2b5926 | 81 | { |
alexwhittemore | 0:7fd45d2b5926 | 82 | // init pins selected by the mask |
alexwhittemore | 0:7fd45d2b5926 | 83 | uint32_t pin = LPC_GPIO0_BASE + port * 32; |
alexwhittemore | 0:7fd45d2b5926 | 84 | for ( uint32_t pinmask = mask; pinmask !=0; pinmask >>= 1 ) |
alexwhittemore | 0:7fd45d2b5926 | 85 | { |
alexwhittemore | 0:7fd45d2b5926 | 86 | if ( pinmask & 1 ) |
alexwhittemore | 0:7fd45d2b5926 | 87 | { |
alexwhittemore | 0:7fd45d2b5926 | 88 | // set PINSEL bits to 0b00 (GPIO) |
alexwhittemore | 0:7fd45d2b5926 | 89 | PINSELREG(pin) &= ~PINSELMASK(pin, 3); |
alexwhittemore | 0:7fd45d2b5926 | 90 | // set FIODIR bit to 1 (output) |
alexwhittemore | 0:7fd45d2b5926 | 91 | PORTDEF(pin)->FIODIR |= PINMASK(pin); |
alexwhittemore | 0:7fd45d2b5926 | 92 | } |
alexwhittemore | 0:7fd45d2b5926 | 93 | pin++; |
alexwhittemore | 0:7fd45d2b5926 | 94 | } |
alexwhittemore | 0:7fd45d2b5926 | 95 | } |
alexwhittemore | 0:7fd45d2b5926 | 96 | void write(int value) |
alexwhittemore | 0:7fd45d2b5926 | 97 | { |
alexwhittemore | 0:7fd45d2b5926 | 98 | PORTDEFPORT(port)->FIOSET = value & mask; |
alexwhittemore | 0:7fd45d2b5926 | 99 | PORTDEFPORT(port)->FIOCLR = ~value & mask; |
alexwhittemore | 0:7fd45d2b5926 | 100 | } |
alexwhittemore | 0:7fd45d2b5926 | 101 | int read() |
alexwhittemore | 0:7fd45d2b5926 | 102 | { |
alexwhittemore | 0:7fd45d2b5926 | 103 | return PORTDEFPORT(port)->FIOPIN & mask; |
alexwhittemore | 0:7fd45d2b5926 | 104 | } |
alexwhittemore | 0:7fd45d2b5926 | 105 | FastPortOut& operator= (int value) { write(value); return *this; }; |
alexwhittemore | 0:7fd45d2b5926 | 106 | FastPortOut& operator= (FastPortOut& rhs) { return write(rhs.read()); }; |
alexwhittemore | 0:7fd45d2b5926 | 107 | operator int() { return read(); }; |
alexwhittemore | 0:7fd45d2b5926 | 108 | }; |
alexwhittemore | 0:7fd45d2b5926 | 109 | |
alexwhittemore | 0:7fd45d2b5926 | 110 | // usage: MaskedPortOut<Port0, mask> led2; |
alexwhittemore | 0:7fd45d2b5926 | 111 | // then use the same assignment operators as with DigitalOut |
alexwhittemore | 0:7fd45d2b5926 | 112 | template <enum PortName port, uint32_t mask = 0xFFFFFFFF> class MaskedPortOut |
alexwhittemore | 0:7fd45d2b5926 | 113 | { |
alexwhittemore | 0:7fd45d2b5926 | 114 | public: |
alexwhittemore | 0:7fd45d2b5926 | 115 | MaskedPortOut() |
alexwhittemore | 0:7fd45d2b5926 | 116 | { |
alexwhittemore | 0:7fd45d2b5926 | 117 | // init pins selected by the mask |
alexwhittemore | 0:7fd45d2b5926 | 118 | uint32_t pin = LPC_GPIO0_BASE + port * 32; |
alexwhittemore | 0:7fd45d2b5926 | 119 | for ( uint32_t pinmask = mask; pinmask !=0; pinmask >>= 1 ) |
alexwhittemore | 0:7fd45d2b5926 | 120 | { |
alexwhittemore | 0:7fd45d2b5926 | 121 | if ( pinmask & 1 ) |
alexwhittemore | 0:7fd45d2b5926 | 122 | { |
alexwhittemore | 0:7fd45d2b5926 | 123 | // set PINSEL bits to 0b00 (GPIO) |
alexwhittemore | 0:7fd45d2b5926 | 124 | PINSELREG(pin) &= ~PINSELMASK(pin, 3); |
alexwhittemore | 0:7fd45d2b5926 | 125 | // set FIODIR bit to 1 (output) |
alexwhittemore | 0:7fd45d2b5926 | 126 | PORTDEF(pin)->FIODIR |= PINMASK(pin); |
alexwhittemore | 0:7fd45d2b5926 | 127 | } |
alexwhittemore | 0:7fd45d2b5926 | 128 | pin++; |
alexwhittemore | 0:7fd45d2b5926 | 129 | } |
alexwhittemore | 0:7fd45d2b5926 | 130 | // set mask |
alexwhittemore | 0:7fd45d2b5926 | 131 | PORTDEFPORT(port)->FIOMASK = mask; |
alexwhittemore | 0:7fd45d2b5926 | 132 | } |
alexwhittemore | 0:7fd45d2b5926 | 133 | void write(int value) |
alexwhittemore | 0:7fd45d2b5926 | 134 | { |
alexwhittemore | 0:7fd45d2b5926 | 135 | PORTDEFPORT(port)->FIOPIN = value; |
alexwhittemore | 0:7fd45d2b5926 | 136 | } |
alexwhittemore | 0:7fd45d2b5926 | 137 | int read() |
alexwhittemore | 0:7fd45d2b5926 | 138 | { |
alexwhittemore | 0:7fd45d2b5926 | 139 | return PORTDEFPORT(port)->FIOPIN; |
alexwhittemore | 0:7fd45d2b5926 | 140 | } |
alexwhittemore | 0:7fd45d2b5926 | 141 | MaskedPortOut& operator= (int value) { write(value); return *this; }; |
alexwhittemore | 0:7fd45d2b5926 | 142 | MaskedPortOut& operator= (MaskedPortOut& rhs) { return write(rhs.read()); }; |
alexwhittemore | 0:7fd45d2b5926 | 143 | operator int() { return read(); }; |
alexwhittemore | 0:7fd45d2b5926 | 144 | }; |
alexwhittemore | 0:7fd45d2b5926 | 145 | |
alexwhittemore | 0:7fd45d2b5926 | 146 | #endif |