{ | { | ||||
for (uint8_t i=0; i < rowCount; i++) | for (uint8_t i=0; i < rowCount; i++) | ||||
{ | { | ||||
ptrsRows[i]->process(activeHigh); | |||||
ptrsRows[i]->process(); | |||||
} | } | ||||
} | } |
private: | private: | ||||
RowBase *const *const ptrsRows; //array of row pointers | RowBase *const *const ptrsRows; //array of row pointers | ||||
const uint8_t rowCount; | const uint8_t rowCount; | ||||
const bool activeHigh; //logic level of strobe pin: 0=activeLow, 1=activeHigh | |||||
public: | public: | ||||
Matrix( RowBase *const ptrsRows[], const uint8_t rowCount, const bool activeHigh) | |||||
: ptrsRows(ptrsRows), rowCount(rowCount), activeHigh(activeHigh) {} | |||||
Matrix( RowBase *const ptrsRows[], const uint8_t rowCount) | |||||
: ptrsRows(ptrsRows), rowCount(rowCount) {} | |||||
void scan(); | void scan(); | ||||
}; | }; | ||||
#endif | #endif |
/* | /* | ||||
process() scans the row and calls any newly pressed or released keys. | process() scans the row and calls any newly pressed or released keys. | ||||
*/ | */ | ||||
void Row::process(const bool activeHigh) | |||||
void Row::process() | |||||
{ | { | ||||
//these variables are all bitwise, one bit per key | //these variables are all bitwise, one bit per key | ||||
uint8_t rowState; //1 means pressed, 0 means released | uint8_t rowState; //1 means pressed, 0 means released | ||||
uint8_t debouncedChanged; //1 means debounced changed | uint8_t debouncedChanged; //1 means debounced changed | ||||
wait(); | wait(); | ||||
rowState = scanner.scan(rowEnd, activeHigh); | |||||
rowState = scanner.scan(rowEnd); | |||||
debouncedChanged = debouncer.debounce(rowState, debounced); | debouncedChanged = debouncer.debounce(rowState, debounced); | ||||
pressRelease(rowEnd, debouncedChanged); | pressRelease(rowEnd, debouncedChanged); | ||||
} | } |
Row( RowPort &refRowPort, const uint8_t rowPin, | Row( RowPort &refRowPort, const uint8_t rowPin, | ||||
ColPort *const ptrsColPorts[], const uint8_t colPortCount, Key *const ptrsKeys[]) | ColPort *const ptrsColPorts[], const uint8_t colPortCount, Key *const ptrsKeys[]) | ||||
: RowBase(ptrsKeys), scanner(refRowPort, rowPin, ptrsColPorts, colPortCount) { } | : RowBase(ptrsKeys), scanner(refRowPort, rowPin, ptrsColPorts, colPortCount) { } | ||||
virtual void process(const bool activeHigh); | |||||
virtual void process(); | |||||
}; | }; | ||||
#endif | #endif |
void pressRelease(const uint16_t rowEnd, const uint8_t debouncedChanged); | void pressRelease(const uint16_t rowEnd, const uint8_t debouncedChanged); | ||||
public: | public: | ||||
RowBase(Key *const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { } | RowBase(Key *const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { } | ||||
virtual void process(const bool activeHigh)=0; | |||||
virtual void process()=0; | |||||
}; | }; | ||||
#endif | #endif |
class RowScannerInterface | class RowScannerInterface | ||||
{ | { | ||||
public: | public: | ||||
virtual uint8_t scan(uint16_t& rowEnd, const bool activeHigh)=0; | |||||
virtual uint8_t scan(uint16_t& rowEnd)=0; | |||||
}; | }; | ||||
#endif | #endif | ||||
Strobes the row and reads the columns. | Strobes the row and reads the columns. | ||||
Strobe is on for shortest possible time to preserve IR LED on DodoHand's optic switch. | 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) | |||||
uint8_t RowScanner_BitManipulation::scan(uint16_t& rowEnd) | |||||
{ | { | ||||
//strobe row on | //strobe row on | ||||
if (activeHigh) | if (activeHigh) | ||||
refRowPort.setActivePinHigh(rowPin); | refRowPort.setActivePinHigh(rowPin); | ||||
} | } | ||||
return getRowState(rowEnd, activeHigh); | |||||
return getRowState(rowEnd); | |||||
} | } | ||||
/* | /* | ||||
rowEnd is bitwise, where 1 bit corrsiponds to place immediatly after last key of row. | 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. | 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) | |||||
uint8_t RowScanner_BitManipulation::getRowState(uint16_t& rowEnd) | |||||
{ | { | ||||
uint16_t rowMask = 1; //bitwise, one col per bit, active col bit is 1 | 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 | uint8_t rowState = 0; //bitwise, one key per bit, 1 means key is pressed |
class RowScanner_BitManipulation : public RowScannerInterface | class RowScanner_BitManipulation : public RowScannerInterface | ||||
{ | { | ||||
private: | private: | ||||
static const bool activeHigh; //logic level of strobe pin: 0=activeLow, 1=activeHigh | |||||
RowPort &refRowPort; //this row's IC port | RowPort &refRowPort; //this row's IC port | ||||
const uint8_t rowPin; //bitwise, 1 indicates IC pin connected to this row | const uint8_t rowPin; //bitwise, 1 indicates IC pin connected to this row | ||||
ColPort *const ptrsColPorts[], const uint8_t colPortCount) | ColPort *const ptrsColPorts[], const uint8_t colPortCount) | ||||
: refRowPort(refRowPort), rowPin(rowPin), | : refRowPort(refRowPort), rowPin(rowPin), | ||||
ptrsColPorts(ptrsColPorts), colPortCount(colPortCount) {} | ptrsColPorts(ptrsColPorts), colPortCount(colPortCount) {} | ||||
virtual uint8_t scan(uint16_t& rowEnd, const bool activeHigh); | |||||
uint8_t getRowState(uint16_t& rowEnd, const bool activeHigh); | |||||
virtual uint8_t scan(uint16_t& rowEnd); | |||||
uint8_t getRowState(uint16_t& rowEnd); | |||||
}; | }; | ||||
#endif | #endif |