diff --git a/IODevice.h b/IODevice.h index 6f12969..a8dfc1b 100644 --- a/IODevice.h +++ b/IODevice.h @@ -161,6 +161,8 @@ public: // once the GPIO port concerned has been read. void setGPIOInterruptPin(int16_t pinNumber); + // Method to check if pins will overlap before creating new device. + static bool checkNoOverlap(VPIN firstPin, uint8_t nPins=1, uint8_t i2cAddress=0); protected: @@ -234,9 +236,6 @@ protected: // pin low if an input changes state. int16_t _gpioInterruptPin = -1; - // Method to check if pins will overlap before creating new device. - static bool checkNoOverlap(VPIN firstPin, uint8_t nPins=1, uint8_t i2cAddress=0); - // Static support function for subclass creation static void addDevice(IODevice *newDevice); diff --git a/IO_LEWDUINO.h b/IO_LEWDUINO.h index dfa549d..47bb3f2 100644 --- a/IO_LEWDUINO.h +++ b/IO_LEWDUINO.h @@ -16,13 +16,16 @@ * You should have received a copy of the GNU General Public License * along with CommandStation. If not, see . */ -#ifndef IO_DNIN8_h - #define IO_DNIN8_h +#ifndef IO_LEWDUINO_h + #define IO_LEWDUINO_h #include +#include "defines.h" +#include "IODevice.h" + #define PIN_MASK(bit) (0x80>>(bit%8)) -#define GET_BIT(bit) (_pinValues[bit/8] & PIN_MASK(bit) ) -#define SET_BIT(bit) _pinValues[bit/8] |= PIN_MASK(bit) -#define CLR_BIT(bit) _pinValues[bit/8] &= ~PIN_MASK(bit) +#define GET_BIT(x) (_pinValues[(x)/8] & PIN_MASK((x)) ) +#define SET_BIT(x) _pinValues[(x)/8] |= PIN_MASK((x)) +#define CLR_BIT(x) _pinValues[(x)/8] &= ~PIN_MASK((x)) #define DIAG_IO @@ -50,7 +53,7 @@ public: _deviceState = DEVSTATE_NORMAL; pinMode(_latchPin,OUTPUT); pinMode(_clockPin,OUTPUT); - pinMode(_dataPin,INPUT_PULLUP); + pinMode(_dataPin,_pinMap?INPUT_PULLUP:OUTPUT); _display(); } @@ -67,22 +70,27 @@ void _loopInput(unsigned long currentMicros) { //set latch to HIGH to freeze & store parallel data ArduinoPins::fastWriteDigital(_latchPin, HIGH); - delayMicroseconds(20); + delayMicroseconds(50); //set latch to LOW to enable the data to be transmitted serially ArduinoPins::fastWriteDigital(_latchPin, LOW); + delayMicroseconds(50); // stream in the bitmap useing mapping order provided at constructor - for (int xmitBit=0;xmitBit<_nShiftBytes*8; xmitBit++) { - ArduinoPins::fastWriteDigital(_clockPin, LOW); - delayMicroseconds(4); - bool data = ArduinoPins::fastReadDigital(_dataPin); - byte map=_pinMap[xmitBit%8]; - //DIAG(F("DIN x=%d,d=%d m=%x"),xmitBit,data,map); - if (data) _pinValues[xmitBit/8] |= map; - else _pinValues[xmitBit/8] &= ~map; - ArduinoPins::fastWriteDigital(_clockPin, HIGH); - } - // DIAG(F("DIN %x"),_pinValues[0]); + for (int xmitByte=0;xmitByte<_nShiftBytes; xmitByte++) { + byte newByte=0; + for (int xmitBit=0;xmitBit<8; xmitBit++) { + ArduinoPins::fastWriteDigital(_clockPin, LOW); + delayMicroseconds(20); + bool data = ArduinoPins::fastReadDigital(_dataPin); + byte map=_pinMap[xmitBit]; + if (data) newByte |= map; + else newByte &= ~map; + ArduinoPins::fastWriteDigital(_clockPin, HIGH); + delayMicroseconds(20); + } + _pinValues[xmitByte]=newByte; + DIAG(F("DIN %x=%x"),xmitByte, newByte); + } } void _loopOutput() { @@ -98,7 +106,9 @@ void _loopOutput() { } int _read(VPIN vpin) override { - return GET_BIT(vpin - _firstVpin); + int pin=vpin - _firstVpin; + bool b=GET_BIT(pin); + return b?1:0; } void _write(VPIN vpin, int value) override { @@ -112,14 +122,14 @@ void _loopOutput() { } void _display() override { - DIAG(F("IO_LEWDUINO %SPUT Configured on VPins:%d-%d"), + DIAG(F("IO_LEWDUINO %SPUT Configured on VPins:%d-%d shift=%d"), _pinMap?F("IN"):F("OUT"), (int)_firstVpin, - (int)_firstVpin+_nPins-1); + (int)_firstVpin+_nPins-1, _nShiftBytes*8); } private: - static const unsigned long POLL_MICROS=100000; // 10 / S + static const unsigned long POLL_MICROS=1000000; // 10 / S unsigned long _prevMicros; int _nShiftBytes=0; VPIN _latchPin,_clockPin,_dataPin; @@ -128,23 +138,26 @@ private: const byte* _pinMap; // NULL in output mode }; -class IO_DNIN8 { +class IO_DNIN8 { public: - static void create(VPIN firstVpin, int nPins, byte latchPin, byte clockPin, byte dataPin ) + static void create(VPIN firstVpin, int nPins, byte clockPin, byte latchPin, byte dataPin ) { // input arrives as board pin 0,7,6,5,1,2,3,4 static const byte pinmap[8]={0x80,0x01,0x02,0x04,0x40,0x20,0x10,0x08}; - new IO_LEWDUINO( firstVpin, nPins, latchPin, clockPin, dataPin,pinmap); + if (IODevice::checkNoOverlap(firstVpin,nPins)) + new IO_LEWDUINO( firstVpin, nPins, clockPin, latchPin, dataPin,pinmap); } }; -class IO_DNIN8K { +class IO_DNIN8K { public: static void create(VPIN firstVpin, int nPins, byte clockPin, byte latchPin, byte dataPin ) { - static const byte pinmap[8]={0x80,0x01,0x02,0x04,0x40,0x20,0x10,0x08}; // TODO - new IO_LEWDUINO( firstVpin, nPins, clockPin, latchPin, dataPin,pinmap); + // input arrives as board pin 0, 1, 2, 3, 4, 5, 6, 7 + static const byte pinmap[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; + if (IODevice::checkNoOverlap(firstVpin,nPins)) + new IO_LEWDUINO( firstVpin, nPins, clockPin, latchPin, dataPin,pinmap); } }; @@ -152,7 +165,8 @@ class IO_DNOUT8 { public: static void create(VPIN firstVpin, int nPins, byte clockPin, byte latchPin, byte dataPin ) { - new IO_LEWDUINO( firstVpin, nPins, clockPin, latchPin, dataPin,NULL); + if (IODevice::checkNoOverlap(firstVpin,nPins)) + new IO_LEWDUINO( firstVpin, nPins, clockPin, latchPin, dataPin,NULL); } }; diff --git a/Release_Notes/duinogear.md b/Release_Notes/duinogear.md new file mode 100644 index 0000000..dfcb4dc --- /dev/null +++ b/Release_Notes/duinogear.md @@ -0,0 +1,20 @@ +Using Lew's Duino Gear boards: + +1. DNIN8 Input + This is a shift-register implementation of a digital input collector. + Multiple DNIN8 may be connected in sequence but it is IMPORTANT that the software + configuratuion correctly represents the number of boards connected otherwise the results will be meaningless. + + Use in myAnimation.h + + HAL(IO_DNIN8, firstVpin, numPins, clockPin, latchPin, dataPin) + + e.g. + HAL(IO_DNIN8, 400, 16, 40, 42, 44) + This will create virtaul pins 400-415 using two DNIN8 boards connected in sequence. + Vpins 400-407 will be on the first board (closest to the CS) and 408-415 on the second. + + Note: 16 pins uses two boards. You may specify a non-multiple-of-8 pins but this will be rounded up to a multiple of 8 and you must connect ONLY the number of boards that this takes. + + This example uses Arduino GPIO pins 40,42,44 as these are conveniently side-by-side on a Mega which is easier when you are using a 3 strand cable. + \ No newline at end of file