diff --git a/src/Row.cpp b/src/Row.cpp index d1bbd56..1e6abe4 100644 --- a/src/Row.cpp +++ b/src/Row.cpp @@ -1,7 +1,3 @@ -/* debounce() sets debounced and returns debouncedChanged. All variables are bitwise. -For parameter, 1 means pressed, 0 means released. -For return, 1 means debounced changed. -*/ #include "Row.h" /* diff --git a/src/Row.h b/src/Row.h index 4f42209..2e83df6 100644 --- a/src/Row.h +++ b/src/Row.h @@ -2,15 +2,12 @@ #define ROW_H #include -//#include -#include +#include #include /* Configuration ------------- -define and initilize DELAY_MICROSECONDS in sketch. - const unsigned int RowBase::DELAY_MICROSECONDS = 0; Instantiation ------------- @@ -19,12 +16,12 @@ Instantiation class Row : public RowBase { private: - //RowScanner_BitManipulation scanner; - RowScanner_Arduino scanner; + RowScanner_PinsArray scanner; Debouncer_4Samples debouncer; public: //Row constructor was like Row_DH constructor - Row(const uint8_t strobePin, const uint8_t readPins[], const uint8_t READ_PIN_COUNT, Key *const ptrsKeys[]) + Row(const uint8_t strobePin, const uint8_t readPins[], const uint8_t READ_PIN_COUNT, + Key *const ptrsKeys[]) : RowBase(ptrsKeys), scanner(strobePin, readPins, READ_PIN_COUNT) { } virtual void process(); }; diff --git a/src/RowBase.cpp b/src/RowBase.cpp index d2391ab..00fc002 100644 --- a/src/RowBase.cpp +++ b/src/RowBase.cpp @@ -23,14 +23,14 @@ Tactile switch MJTP series bounce 10 ms http://www.apem.com/files/apem/brochures Avoid sampling the switch input at a rate synchronous to events in the environment that might create periodic EMI. For instance, 50 and 60 Hz. -The largest allowabl DELAY_MICROSECONDS is 65535 (.065535 second). +The largest allowable DELAY_MICROSECONDS is 65535 (.065535 seconds). Polling I2C may slow the scan rate enough so that no additional delay is needed: const unsigned int Row::DELAY_MICROSECONDS = 0; Slow-scan trick for debug messages that print too fast and not aligned, add this to sketch loop(): delay(500); - Keyboard.println(""); + Keyboard.println(F("")); That way debug messages are printed at a managable rate, and each scan starts a new line. */ void RowBase::wait() diff --git a/src/RowBase.h b/src/RowBase.h index 7074f13..c6dfd4b 100644 --- a/src/RowBase.h +++ b/src/RowBase.h @@ -5,6 +5,9 @@ #include /* RowBase is an abstract base class. + +Define and initilize DELAY_MICROSECONDS in sketch. + const unsigned int RowBase::DELAY_MICROSECONDS = 0; */ class RowBase { diff --git a/src/RowIOE.cpp b/src/RowIOE.cpp new file mode 100644 index 0000000..a020332 --- /dev/null +++ b/src/RowIOE.cpp @@ -0,0 +1,17 @@ +#include "RowIOE.h" + +/* +process() scans the row and calls any newly pressed or released keys. +*/ +void RowIOE::process() +{ + //these variables are all bitwise, one bit per key + uint8_t rowState; //1 means pressed, 0 means released + uint16_t rowEnd; //1 bit marks positioned after last key of row + uint8_t debouncedChanged; //1 means debounced changed + + wait(); + rowState = scanner.scan(rowEnd); + debouncedChanged = debouncer.debounce(rowState, debounced); + pressRelease(rowEnd, debouncedChanged); +} diff --git a/src/RowIOE.h b/src/RowIOE.h new file mode 100644 index 0000000..13e00e2 --- /dev/null +++ b/src/RowIOE.h @@ -0,0 +1,28 @@ +#ifndef ROWIOE_H +#define ROWIOE_H + +#include +#include +#include + +/* +Simlar to Row but using RowScanner_PinsBitwise. + +Configuration +------------- + +Instantiation +------------- +*/ +class RowIOE : public RowBase +{ + private: + RowScanner_PinsBitwise scanner; + Debouncer_4Samples debouncer; + public: + RowIOE( RowPort& refRowPort, const uint8_t strobePin, + ColPort& refColPort, Key *const ptrsKeys[]) + : RowBase(ptrsKeys), scanner(refRowPort, strobePin, refColPort) { } + virtual void process(); +}; +#endif diff --git a/src/RowScanner_BitManipulation.cpp b/src/RowScanner_BitManipulation.cpp deleted file mode 100644 index 068c58c..0000000 --- a/src/RowScanner_BitManipulation.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "RowScanner_BitManipulation.h" -/* -Strobes the row and reads the columns. -Strobe is on for shortest possible time to preserve IR LED on DodoHand's optic switch. -*/ -uint8_t RowScanner_BitManipulation::scan(uint16_t& rowEnd) -{ - //strobe row on - if (activeHigh) - { - refRowPort.setActivePinHigh(rowPin); - } - else //activeLow - { - refRowPort.setActivePinLow(rowPin); - } - - //read all the column ports - for (uint8_t i=0; i < colPortCount; i++) - { - ptrsColPorts[i]->read(); - } - - //strobe row off - if (activeHigh) - { - refRowPort.setActivePinLow(rowPin); - } - else //activeLow - { - refRowPort.setActivePinHigh(rowPin); - } - - return getRowState(rowEnd); -} - -/* -Copies column pins to rowState. Unused column pins are not copied. -Sets rowEnd and returns rowState. -rowEnd is a bitwise row mask, one col per bit, where active col bit is 1. -At end of function, 1 bit marks place immediatly after last key of row. -rowEnd is a larger type than portMask so that it can not overflow. -*/ -uint8_t RowScanner_BitManipulation::getRowState(uint16_t& rowEnd) -{ - uint8_t rowState = 0; //bitwise, one key per bit, 1 means key is pressed - - rowEnd = 1; - - for (uint8_t i=0; i < colPortCount; i++) //for each col port - { - //bitwise colPins, 1 means pin is connected to column - uint8_t colPins = ptrsColPorts[i]->getColPins(); - - //bitwise colPortState, pin values where set in ColPort::read(), get them now - uint8_t colPortState = ptrsColPorts[i]->getPortState(); - - if (activeHigh) - { - colPortState = ~colPortState; - } - - for ( uint8_t portMask = 1; portMask > 0; portMask <<= 1 ) //shift portMask until overflow - { //for each pin of col port - if (portMask & colPins) //if pin is connected to column - { - if (portMask & ~colPortState) //if pin detected a key press - { - rowState |= rowEnd; //set rowState bit for that key - } - - rowEnd <<= 1; //shift rowEnd to next key - } - } - } - - return rowState; -} diff --git a/src/RowScanner_BitManipulation.h b/src/RowScanner_BitManipulation.h deleted file mode 100644 index f719505..0000000 --- a/src/RowScanner_BitManipulation.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef ROWSCANNER_BITMANIPULATION_H -#define ROWSCANNER_BITMANIPULATION_H -#include -#include -#include -#include -#include - -/* RowScanner_BitManipulation uses bit manipulation to read all pins of one port. -*/ -class RowScanner_BitManipulation : public RowScannerInterface -{ - private: - static const bool activeHigh; //logic level of strobe pin: 0=activeLow, 1=activeHigh - RowPort &refRowPort; //this row's IC port - const uint8_t rowPin; //bitwise, 1 indicates IC pin connected to this row - - ColPort *const *const ptrsColPorts; //array of column ports - const uint8_t colPortCount; - - public: - RowScanner_BitManipulation(RowPort &refRowPort, const uint8_t rowPin, - ColPort *const ptrsColPorts[], const uint8_t colPortCount) - : refRowPort(refRowPort), rowPin(rowPin), - ptrsColPorts(ptrsColPorts), colPortCount(colPortCount) {} - virtual uint8_t scan(uint16_t& rowEnd); - uint8_t getRowState(uint16_t& rowEnd); -}; -#endif diff --git a/src/RowScanner_Arduino.cpp b/src/RowScanner_PinsArray.cpp similarity index 88% rename from src/RowScanner_Arduino.cpp rename to src/RowScanner_PinsArray.cpp index 4421a33..e2d9341 100644 --- a/src/RowScanner_Arduino.cpp +++ b/src/RowScanner_PinsArray.cpp @@ -1,4 +1,4 @@ -#include "RowScanner_Arduino.h" +#include "RowScanner_PinsArray.h" /* Strobes the row and reads the columns. @@ -7,7 +7,7 @@ rowEnd is a bitwise row mask, one col per bit, where active col bit is 1. At end of function, 1 bit marks place immediatly after last key of row. rowEnd is a larger type than portMask so that it can not overflow. */ -uint8_t RowScanner_Arduino::scan(uint16_t& rowEnd) +uint8_t RowScanner_PinsArray::scan(uint16_t& rowEnd) { uint8_t rowState = 0; rowEnd = 1; @@ -23,7 +23,7 @@ uint8_t RowScanner_Arduino::scan(uint16_t& rowEnd) } delayMicroseconds(3); //time to stablize voltage - //read all the column ports + //read all the column pins for (uint8_t i=0; i < READ_PIN_COUNT; i++) { if ( digitalRead(readPins[i]) == activeHigh ) diff --git a/src/RowScanner_Arduino.h b/src/RowScanner_PinsArray.h similarity index 80% rename from src/RowScanner_Arduino.h rename to src/RowScanner_PinsArray.h index 39f2779..5b14baa 100644 --- a/src/RowScanner_Arduino.h +++ b/src/RowScanner_PinsArray.h @@ -1,14 +1,14 @@ -#ifndef ROWSCANNER_ARDUINO_H -#define ROWSCANNER_ARDUINO_H +#ifndef ROWSCANNER_PINSARRAY_H +#define ROWSCANNER_PINSARRAY_H #include #include #include #include #include -/* RowScanner_Arduino class uses Arduino pin numbers (no port name). +/* RowScanner_PinsArray class uses Arduino pin numbers (no port name). */ -class RowScanner_Arduino : public RowScannerInterface +class RowScanner_PinsArray : public RowScannerInterface { private: static const bool activeHigh; //logic level of strobe pin: 0=activeLow, 1=activeHigh @@ -16,7 +16,7 @@ class RowScanner_Arduino : public RowScannerInterface const uint8_t* readPins; //array of read pin numbers const uint8_t READ_PIN_COUNT; //number of read pins public: - RowScanner_Arduino(const uint8_t strobePin, + RowScanner_PinsArray(const uint8_t strobePin, const uint8_t readPins[], const uint8_t READ_PIN_COUNT) : strobePin(strobePin), readPins(readPins), READ_PIN_COUNT(READ_PIN_COUNT) { diff --git a/src/RowScanner_PinsBitwise.cpp b/src/RowScanner_PinsBitwise.cpp new file mode 100644 index 0000000..29bd381 --- /dev/null +++ b/src/RowScanner_PinsBitwise.cpp @@ -0,0 +1,79 @@ +#include "RowScanner_PinsBitwise.h" +/* +Strobes the row and reads the columns. +Strobe is on for shortest possible time to preserve IR LED on DodoHand's optic switch. +*/ +uint8_t RowScanner_PinsBitwise::scan(uint16_t& rowEnd) +{ + //strobe row on + if (activeHigh) + { + refRowPort.setActivePinHigh(strobePin); + } + else //activeLow + { + refRowPort.setActivePinLow(strobePin); + } + delayMicroseconds(3); //time to stablize voltage + + //read all the port pins + refColPort.read(); +/* shows strobing pin 1 and 2, but realy stobing 0 and 1 todo +Keyboard.print(F(" strobePin=")); +Keyboard.print(strobePin); +Keyboard.print(F(", ")); +*/ + //strobe row off + if (activeHigh) + { + refRowPort.setActivePinLow(strobePin); + } + else //activeLow + { + refRowPort.setActivePinHigh(strobePin); + } + + return getRowState(rowEnd); +} + +/* +Copies column pins to rowState. Unused column pins are not copied. +Sets rowEnd and returns rowState. +rowEnd is a bitwise row mask, one col per bit, where active col bit is 1. +At end of function, 1 bit marks place immediatly after last key of row. +rowEnd is a larger type than portMask so that it can not overflow. +*/ +uint8_t RowScanner_PinsBitwise::getRowState(uint16_t& rowEnd) +{ + uint8_t rowState = 0; //bitwise, one key per bit, 1 means key is pressed + uint8_t portMask; //bitwise, 1 bit is a colPortState position + + rowEnd = 1; + + //bitwise colPins, 1 means pin is connected to column + uint8_t colPins = refColPort.getColPins(); + + //bitwise colPortState, pin values where set in ColPort::read(), get them now + uint8_t colPortState = refColPort.getPortState(); + + if (activeHigh) + { + colPortState = ~colPortState; + } + + for ( portMask = 1; portMask > 0; portMask <<= 1 ) //shift portMask until overflow + { //for each pin of col port + if (portMask & colPins) //if pin is connected to column + { + if (portMask & ~colPortState) //if pin detected a key press + { + rowState |= rowEnd; //set rowState bit for that key + } + + rowEnd <<= 1; //shift rowEnd to next key + } + } +//todo Keyboard.print(rowState); + + return rowState; +} diff --git a/src/RowScanner_PinsBitwise.h b/src/RowScanner_PinsBitwise.h new file mode 100644 index 0000000..8aaf805 --- /dev/null +++ b/src/RowScanner_PinsBitwise.h @@ -0,0 +1,26 @@ +#ifndef ROWSCANNER_PINSBITWISE_H +#define ROWSCANNER_PINSBITWISE_H +#include +#include +#include +#include +#include + +/* RowScanner_PinsBitwise uses bit manipulation to read all pins of one port. +*/ +class RowScanner_PinsBitwise : public RowScannerInterface +{ + private: + static const bool activeHigh; //logic level of strobe pin: 0=activeLow, 1=activeHigh + RowPort& refRowPort; //this row's IC port + const uint8_t strobePin; //bitwise, 1 indicates IC pin connected to this row + ColPort& refColPort; + public: + RowScanner_PinsBitwise(RowPort &refRowPort, const uint8_t strobePin, + ColPort& refColPort) + : refRowPort(refRowPort), strobePin(strobePin), + refColPort(refColPort) {} + virtual uint8_t scan(uint16_t& rowEnd); + uint8_t getRowState(uint16_t& rowEnd); +}; +#endif