class RowScannerInterface | class RowScannerInterface | ||||
{ | { | ||||
public: | public: | ||||
virtual read_pins_t scan(read_pins_mask_t& rowEnd)=0; | |||||
// virtual read_pins_t scan(read_pins_mask_t& rowEnd)=0; | |||||
// todo, remove RowScannerInterface because | |||||
// some RowScanners will return ColPort e.g. RowScanner_PinsBitwise | |||||
}; | }; | ||||
#endif | #endif | ||||
Strobes the row and reads the columns. | Strobes the row and reads the columns. | ||||
Sets rowEnd and returns rowState. | Sets rowEnd and returns rowState. | ||||
*/ | */ | ||||
read_pins_t RowScanner_PinsBitwise::scan(read_pins_mask_t& rowEnd) | |||||
ColPort* const RowScanner_PinsBitwise::scan(read_pins_mask_t& rowEnd) | |||||
{ | { | ||||
//strobe row on | //strobe row on | ||||
if (activeHigh) | if (activeHigh) | ||||
refRowPort.setActivePinHigh(strobePin); | 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(read_pins_mask_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 | |||||
} | |||||
} | |||||
return rowState; | |||||
// return getRowState(refColPort, rowEnd); | |||||
return &refColPort; | |||||
} | } |
: refRowPort(refRowPort), strobePin(strobePin), | : refRowPort(refRowPort), strobePin(strobePin), | ||||
refColPort(refColPort) {} | refColPort(refColPort) {} | ||||
static const bool activeHigh; //logic level of strobe pin: 0=activeLow, 1=activeHigh | static const bool activeHigh; //logic level of strobe pin: 0=activeLow, 1=activeHigh | ||||
virtual read_pins_t scan(read_pins_mask_t& rowEnd); | |||||
uint8_t getRowState(read_pins_mask_t& rowEnd); | |||||
virtual ColPort* const scan(read_pins_mask_t& rowEnd); | |||||
}; | }; | ||||
#endif | #endif |
void Row_IOE::process() | void Row_IOE::process() | ||||
{ | { | ||||
//these variables are all bitwise, one bit per key | //these variables are all bitwise, one bit per key | ||||
read_pins_t rowState; //1 means pressed, 0 means released | |||||
uint8_t rowState; //1 means pressed, 0 means released | |||||
read_pins_mask_t rowEnd; //1 bit marks positioned after last key of row | read_pins_mask_t rowEnd; //1 bit marks positioned after last key of row | ||||
read_pins_t debouncedChanged; //1 means debounced changed | |||||
uint8_t debouncedChanged; //1 means debounced changed | |||||
ColPort* ptrColPort; //new | |||||
rowState = scanner.scan(rowEnd); | |||||
ptrColPort = scanner.scan(rowEnd); | |||||
rowState = getRowState(ptrColPort, rowEnd); //new | |||||
debouncedChanged = debouncer.debounce(rowState, debounced); | debouncedChanged = debouncer.debounce(rowState, debounced); | ||||
pressRelease(rowEnd, debouncedChanged); | pressRelease(rowEnd, debouncedChanged); | ||||
} | } | ||||
/* | |||||
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 Row_IOE::getRowState(ColPort* ptrColPort, read_pins_mask_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 = ptrColPort->getColPins(); | |||||
//bitwise colPortState, pin values where set in ColPort::read(), get them now | |||||
uint8_t colPortState = ptrColPort->getPortState(); | |||||
/*if (activeHigh) //'activeHigh' was not declared in this scope | |||||
{ | |||||
colPortState = ~colPortState; //todo configure IOE polarity to take care of this | |||||
}*/ | |||||
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 | |||||
} | |||||
} | |||||
return rowState; | |||||
} |
#include <RowBase.h> | #include <RowBase.h> | ||||
#include <RowScanner_PinsBitwise.h> | #include <RowScanner_PinsBitwise.h> | ||||
#include <Debouncer_4Samples.h> | #include <Debouncer_4Samples.h> | ||||
#include <ColPort.h> | |||||
/* Row_DH_IOE is a row connected to an Input/Output Expander. | /* Row_DH_IOE is a row connected to an Input/Output Expander. | ||||
ColPort& refColPort, Key *const ptrsKeys[]) | ColPort& refColPort, Key *const ptrsKeys[]) | ||||
: RowBase(ptrsKeys), scanner(refRowPort, strobePin, refColPort) { } | : RowBase(ptrsKeys), scanner(refRowPort, strobePin, refColPort) { } | ||||
void process(); | void process(); | ||||
uint8_t getRowState(ColPort* refColPort, read_pins_mask_t& rowEnd); | |||||
}; | }; | ||||
#endif | #endif |