Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
FastIO.h
00001 #ifndef __FAST_IO_H 00002 #define __FAST_IO_H 00003 00004 #include "mbed.h" 00005 00006 // Super-fast DigitalOut-like class for mbed 00007 // by Igor Skochinsky 00008 00009 // includes FastOut, FastPortOut and MaskedPortOut classes 00010 // usage: 00011 // FastOut<LED2> led2; 00012 // FastPortOut<Port0, LED_MASK> ledport2; 00013 // MaskedPortOut<Port0, LED_MASK> ledport3; 00014 // led2 = 1; 00015 // ledport2 = LED_MASK; 00016 // ledport3 = LED_MASK; 00017 // MaskedPortOut works the same way as FastPortOut, but it pre-sets the pin mask so that write can be done in one operation 00018 // this makes things faster but you can't control other pins of the port, even with other classes 00019 00020 00021 // pin definitions in PinNames.h start from LPC_GPIO0_BASE for P0_0 and there are 32 pins to a port (0 to 31) 00022 // Thus: 00023 // pin = LPC_GPIO0_BASE + port * 32 + bit 00024 // port = (pin - LPC_GPIO0_BASE) / 32 00025 // bit = (pin - LPC_GPIO0_BASE) % 32 00026 00027 #define PORTNO(pin) (((pin) - P0_0)/32) 00028 #define BITNO(pin) (((pin) - P0_0)%32) 00029 00030 // calculate the GPIO port definition for the pin 00031 // we rely on the fact that port structs are 0x20 bytes apart 00032 #define PORTDEF(pin) ((LPC_GPIO_TypeDef*)(LPC_GPIO0_BASE + PORTNO(pin)*0x20)) 00033 00034 #define PORTDEFPORT(port) ((LPC_GPIO_TypeDef*)(LPC_GPIO0_BASE + port*0x20)) 00035 00036 // calculate the mask for the pin's bit in the port 00037 #define PINMASK(pin) (1UL << BITNO(pin)) 00038 00039 // each port takes two PINSEL registers (8 bytes or 64 bits) 00040 // so there are 16 pins per PINSEL 00041 #define PINSELREG(pin) (*(volatile uint32_t*)(LPC_PINCON_BASE + 4*(((pin) - P0_0)/16))) 00042 #define PINSELMASK(pin, v) (v << (((pin - P0_0)%16)*2) ) 00043 00044 // usage: FastOut<LED2> led2; 00045 // then use the same assignment operators as with DigitalOut 00046 template <PinName pin> class FastOut 00047 { 00048 public: 00049 FastOut() 00050 { 00051 // set PINSEL bits to 0b00 (GPIO) 00052 PINSELREG(pin) &= ~PINSELMASK(pin, 3); 00053 // set FIODIR bit to 1 (output) 00054 PORTDEF(pin)->FIODIR |= PINMASK(pin); 00055 } 00056 void write(int value) 00057 { 00058 if ( value ) 00059 PORTDEF(pin)->FIOSET = PINMASK(pin); 00060 else 00061 PORTDEF(pin)->FIOCLR = PINMASK(pin); 00062 } 00063 int read() 00064 { 00065 return PORTDEF(pin)->FIOPIN & PINMASK(pin) != 0; 00066 } 00067 FastOut& operator= (int value) { write(value); return *this; }; 00068 FastOut& operator= (FastOut& rhs) { return write(rhs.read()); }; 00069 operator int() { return read(); }; 00070 }; 00071 00072 #define PINSELREG(pin) (*(volatile uint32_t*)(LPC_PINCON_BASE + 4*(((pin) - P0_0)/16))) 00073 #define PINSELMASK(pin, v) (v << (((pin - P0_0)%16)*2) ) 00074 00075 // usage: FastPortOut<Port0, mask> led2; 00076 // then use the same assignment operators as with DigitalOut 00077 template <enum PortName port, uint32_t mask = 0xFFFFFFFF> class FastPortOut 00078 { 00079 public: 00080 FastPortOut() 00081 { 00082 // init pins selected by the mask 00083 uint32_t pin = LPC_GPIO0_BASE + port * 32; 00084 for ( uint32_t pinmask = mask; pinmask !=0; pinmask >>= 1 ) 00085 { 00086 if ( pinmask & 1 ) 00087 { 00088 // set PINSEL bits to 0b00 (GPIO) 00089 PINSELREG(pin) &= ~PINSELMASK(pin, 3); 00090 // set FIODIR bit to 1 (output) 00091 PORTDEF(pin)->FIODIR |= PINMASK(pin); 00092 } 00093 pin++; 00094 } 00095 } 00096 void write(int value) 00097 { 00098 PORTDEFPORT(port)->FIOSET = value & mask; 00099 PORTDEFPORT(port)->FIOCLR = ~value & mask; 00100 } 00101 int read() 00102 { 00103 return PORTDEFPORT(port)->FIOPIN & mask; 00104 } 00105 FastPortOut& operator= (int value) { write(value); return *this; }; 00106 FastPortOut& operator= (FastPortOut& rhs) { return write(rhs.read()); }; 00107 operator int() { return read(); }; 00108 }; 00109 00110 // usage: MaskedPortOut<Port0, mask> led2; 00111 // then use the same assignment operators as with DigitalOut 00112 template <enum PortName port, uint32_t mask = 0xFFFFFFFF> class MaskedPortOut 00113 { 00114 public: 00115 MaskedPortOut() 00116 { 00117 // init pins selected by the mask 00118 uint32_t pin = LPC_GPIO0_BASE + port * 32; 00119 for ( uint32_t pinmask = mask; pinmask !=0; pinmask >>= 1 ) 00120 { 00121 if ( pinmask & 1 ) 00122 { 00123 // set PINSEL bits to 0b00 (GPIO) 00124 PINSELREG(pin) &= ~PINSELMASK(pin, 3); 00125 // set FIODIR bit to 1 (output) 00126 PORTDEF(pin)->FIODIR |= PINMASK(pin); 00127 } 00128 pin++; 00129 } 00130 // set mask 00131 PORTDEFPORT(port)->FIOMASK = mask; 00132 } 00133 void write(int value) 00134 { 00135 PORTDEFPORT(port)->FIOPIN = value; 00136 } 00137 int read() 00138 { 00139 return PORTDEFPORT(port)->FIOPIN; 00140 } 00141 MaskedPortOut& operator= (int value) { write(value); return *this; }; 00142 MaskedPortOut& operator= (MaskedPortOut& rhs) { return write(rhs.read()); }; 00143 operator int() { return read(); }; 00144 }; 00145 00146 #endif
Generated on Mon Jul 18 2022 17:38:08 by
1.7.2