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