diff --git a/src/Row.cpp b/src/Row.cpp index 121ffa4..0042f5b 100644 --- a/src/Row.cpp +++ b/src/Row.cpp @@ -15,9 +15,7 @@ void Row::process(const bool activeHigh) uint8_t debouncedChanged; //1 means debounced changed wait(); - scan(activeHigh); //save column-port-pin values to portState - rowState = getRowState(rowEnd, activeHigh); - //debouncedChanged = debounce(rowState); + //rowState = scanner.scan(rowEnd, activeHigh); debouncedChanged = debouncer.debounce(rowState, debounced); pressRelease(rowEnd, debouncedChanged); } diff --git a/src/Row.h b/src/Row.h index 2881a20..3d60450 100644 --- a/src/Row.h +++ b/src/Row.h @@ -2,6 +2,7 @@ #define ROW_H #include +#include #include /* @@ -17,14 +18,14 @@ Instantiation class Row : public RowBase { private: + RowScanner_BitManipulation scanner; Debouncer_4Samples debouncer; public: Row( RowPort &refRowPort, const uint8_t rowPin, ColPort *const ptrsColPorts[], const uint8_t colPortCount, Key *const ptrsKeys[]) - : RowBase(refRowPort, rowPin, ptrsColPorts, colPortCount, ptrsKeys) - { - Debouncer_4Samples debouncer; - } + : RowBase(ptrsKeys) + , RowScanner_BitManipulation scanner(refRowPort, rowPin, ptrsColPorts, colPortCount) + { } virtual void process(const bool activeHigh); }; #endif diff --git a/src/RowBase.cpp b/src/RowBase.cpp index 534ec56..cc28cf9 100644 --- a/src/RowBase.cpp +++ b/src/RowBase.cpp @@ -35,82 +35,6 @@ void RowBase::wait() delayMicroseconds(DELAY_MICROSECONDS); //delay between Row scans to debounce switches } -/* -Strobes the row and reads the columns. -Strobe is on for shortest possible time to preserve IR LED on DodoHand's optic switch. -*/ -void RowBase::scan(const bool activeHigh) -{ - //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); - } -} - -/* -Copies column pins to rowState. Unused column pins are not copied. -Sets rowEnd and returns rowState. -rowEnd is bitwise, where 1 bit corrsiponds to place immediatly after last key of row. -rowEnd and rowMask are larger type than portMask so that they can not overflow. -*/ -uint8_t RowBase::getRowState(uint16_t& rowEnd, const bool activeHigh) -{ - uint16_t rowMask = 1; //bitwise, one col per bit, active col bit is 1 - uint8_t rowState = 0; //bitwise, one key per bit, 1 means key is pressed - - 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 |= rowMask; //set rowState bit for that key - } - - rowMask <<= 1; //shift rowMask to next key - } - } - } - - rowEnd = rowMask; - - return rowState; -} - /* pressRelease() calls key's press() or release() function if it was pressed or released. Both parameters are bitwise. diff --git a/src/RowBase.h b/src/RowBase.h index 0816d1b..20212cc 100644 --- a/src/RowBase.h +++ b/src/RowBase.h @@ -3,8 +3,6 @@ #include #include #include -#include -#include /* RowBase is an abstract base class. */ @@ -14,27 +12,14 @@ class RowBase static const unsigned int DELAY_MICROSECONDS; //delay between each Row scan for debouncing Key *const *const ptrsKeys; //array of Key pointers - 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; - virtual void keyWasPressed(); protected: uint8_t debounced; //bitwise, 1 means pressed, 0 means released void wait(); - void scan(const bool activeHigh); - uint8_t getRowState(uint16_t& rowEnd, const bool activeHigh); void pressRelease(const uint16_t rowEnd, const uint8_t debouncedChanged); public: - RowBase( RowPort &refRowPort, const uint8_t rowPin, - ColPort *const ptrsColPorts[], const uint8_t colPortCount, - Key *const ptrsKeys[]) - : ptrsKeys(ptrsKeys), refRowPort(refRowPort), rowPin(rowPin), - ptrsColPorts(ptrsColPorts), colPortCount(colPortCount), - debounced(0) { } + RowBase(Key *const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { } virtual void process(const bool activeHigh)=0; }; #endif diff --git a/src/RowScannerInterface.h b/src/RowScannerInterface.h new file mode 100644 index 0000000..a7284ff --- /dev/null +++ b/src/RowScannerInterface.h @@ -0,0 +1,18 @@ +#ifndef ROWSCANNERINTERFACE_H +#define ROWSCANNERINTERFACE_H + +/* RowScannerInterface is an interface class. +Sets rowEnd and returns rowState. +rowEnd is bitwise, where 1 bit corrsiponds to place immediatly after last key of row. +rowEnd and rowMask are larger type than portMask so that they can not overflow. +*/ +#include +#include + +class RowScannerInterface +{ + public: + virtual uint8_t scan(uint16_t& rowEnd, const bool activeHigh)=0; +}; +#endif + diff --git a/src/RowScanner_BitManipulation.cpp b/src/RowScanner_BitManipulation.cpp new file mode 100644 index 0000000..7e33b14 --- /dev/null +++ b/src/RowScanner_BitManipulation.cpp @@ -0,0 +1,78 @@ +#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, const bool activeHigh) +{ + //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, activeHigh); +} + +/* +Copies column pins to rowState. Unused column pins are not copied. +Sets rowEnd and returns rowState. +rowEnd is bitwise, where 1 bit corrsiponds to place immediatly after last key of row. +rowEnd and rowMask are larger type than portMask so that they can not overflow. +*/ +uint8_t RowScanner_BitManipulation::getRowState(uint16_t& rowEnd, const bool activeHigh) +{ + uint16_t rowMask = 1; //bitwise, one col per bit, active col bit is 1 + uint8_t rowState = 0; //bitwise, one key per bit, 1 means key is pressed + + 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 |= rowMask; //set rowState bit for that key + } + + rowMask <<= 1; //shift rowMask to next key + } + } + } + + rowEnd = rowMask; + + return rowState; +} diff --git a/src/RowScanner_BitManipulation.h b/src/RowScanner_BitManipulation.h new file mode 100644 index 0000000..2cb93c1 --- /dev/null +++ b/src/RowScanner_BitManipulation.h @@ -0,0 +1,26 @@ +#ifndef ROWSCANNER_BITMANIPULATION_H +#define ROWSCANNER_BITMANIPULATION_H +#include +#include +#include +#include +#include + +class RowScanner_BitManipulation : public RowScannerInterface +{ + private: + 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, const bool activeHigh); + uint8_t getRowState(uint16_t& rowEnd, const bool activeHigh); +}; +#endif