Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
Diff: TinyDigitalIn.h
- Revision:
- 73:4e8ce0b18915
- Parent:
- 48:058ace2aed1d
- Child:
- 77:0b96f6867312
--- a/TinyDigitalIn.h Wed Jan 04 20:14:12 2017 +0000 +++ b/TinyDigitalIn.h Sat Jan 21 19:48:30 2017 +0000 @@ -1,8 +1,10 @@ +#include "mbed.h" + // TinyDigitalIn - a simpler verison of DigitalIn that takes less // memory. // // This version uses the same mbed library infrastructure as the -// regular DigitalIn, but we save a bit of memory by storing only +// regular DigitalIn, but we save a little memory by storing only // the minimum set of fields needed to read the pin. The mbed // DigitalIn has a larger memory footprint because it stores the // full set of machine register pointers for the pin, most of @@ -11,9 +13,11 @@ class TinyDigitalIn { public: - TinyDigitalIn(PinName pin) + TinyDigitalIn(PinName pin) { assignPin(pin); } + TinyDigitalIn() { assignPin(NC); } + + void assignPin(PinName pin) { - // make sure there's a pin connected if (pin != NC) { // initialize the pin as a GPIO Digital In port @@ -22,19 +26,37 @@ // get the register input port and mask pdir = gpio.reg_in; - mask = gpio.mask; - } - else - { - // no pin - set a null read register - pdir = 0; - } + uint32_t mask = gpio.mask; + + // Figure the bit shift: find how many right shifts it takes + // to shift the mask bit into the 0th bit position. This lets + // us pull out the result value in read() as a 0 or 1 by shifting + // the register by this same amount and masking it against 0x01. + // The right shift is slightly more efficient than a conditional + // to convert a bit in the middle of the register to a canonical + // 0 or 1 result, and we have to do the mask anyway to pull out + // the one bit, so this makes the overall read slightly faster. + for (shift = 0 ; + mask != 0 && (mask & 0x00000001) == 0 ; + mask >>= 1, shift++) ; + } + else + { + // not connected - point to a dummy port that always reads as 0 + pdir = (volatile uint32_t *)&pdir_nc; + shift = 0; + } } - inline int read() { return pdir != 0 && (*pdir & mask) ? 1 : 0; } + inline int read() { return (*pdir >> shift) & 0x00000001; } inline operator int() { return read(); } private: - volatile uint32_t *pdir; - uint32_t mask; -}; + volatile uint32_t *pdir; // pointer to GPIO register for this port + uint8_t shift; // number of bits to shift register value to get our port bit + + // pointer to dummy location for NC ports - reads as all 1 bits, + // as though it were wired to a pull-up port that's not connected + // to anything external + static const uint32_t pdir_nc; +} __attribute__((packed));