*/ | */ | ||||
if (keyboard_leds & USB_LED_bit) //if USB_LED_bit is set | if (keyboard_leds & USB_LED_bit) //if USB_LED_bit is set | ||||
{ | { | ||||
refLED.off(); //LED on/off seem inverted, but it works for active high | |||||
refLED.off(); //LED on-off seem inverted, but it works for active high | |||||
} | } | ||||
else | else | ||||
{ | { |
configures column port's configuration and output. | configures column port's configuration and output. | ||||
*/ | */ | ||||
RowPort_PCA9655E::RowPort_PCA9655E(IOExpanderPort& port) | RowPort_PCA9655E::RowPort_PCA9655E(IOExpanderPort& port) | ||||
: port(port), configurationByteCommand(port.num + 6), outputByteCommand(port.num + 2) | |||||
{} | |||||
: port(port), configurationByteCommand(port.num + 6), outputByteCommand(port.num + 2) {} | |||||
void RowPort_PCA9655E::begin() | void RowPort_PCA9655E::begin() | ||||
{ | { |
#include "Row_IOE.h" | |||||
void Row_IOE::process() | |||||
{ | |||||
//these variables are all bitwise, one bit per key | |||||
uint8_t rowState; //1 means pressed, 0 means released | |||||
//read_pins_mask_t rowEnd; //1 bit marks positioned after last key of row | |||||
uint8_t debouncedChanged; //1 means debounced changed | |||||
ColPort* ptrColPort; //new | |||||
uint8_t KEY_COUNT; //new | |||||
ptrColPort = scanner.scan(); | |||||
rowState = getRowState(ptrColPort, KEY_COUNT); //new | |||||
debouncedChanged = debouncer.debounce(rowState, debounced); | |||||
pressRelease(KEY_COUNT, 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, uint8_t& KEY_COUNT) | |||||
{ | |||||
uint8_t rowState = 0; //bitwise, one key per bit, 1 means key is pressed | |||||
uint8_t portMask; //bitwise, 1 bit is a colPortState position | |||||
uint8_t rowEnd; //1 bit marks positioned after last key of row todo rename | |||||
KEY_COUNT = 0; | |||||
//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 | |||||
KEY_COUNT++; | |||||
} | |||||
} | |||||
return rowState; | |||||
} |
#ifndef ROWIOE_H | |||||
#define ROWIOE_H | |||||
#include <RowBase.h> | |||||
#include <RowScanner_PinsBitwise.h> | |||||
#include <Debouncer_4Samples.h> | |||||
#include <ColPort.h> | |||||
/* Row_DH_IOE is a row connected to an Input/Output Expander. | |||||
Instantiation | |||||
------------- | |||||
Definition of DELAY_MICROSECONDS is explained in RowBase.cpp. | |||||
Definition of activeHigh is explained in RowScanner_Interface.h | |||||
Example instantiation of a row: | |||||
const unsigned int RowBase::DELAY_MICROSECONDS = 1000; | |||||
const bool RowScanner_PinsArray::activeHigh = 0; | |||||
const uint8_t IOExpanderPort::ADDR = 0x18; | |||||
IOExpanderPort port1(1, 0); | |||||
RowPort_PCA9655E rowPort1(port1); | |||||
IOExpanderPort port0(0, 0); | |||||
ColPort_PCA9655E colPort0(port0, 1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 ); | |||||
Key* const ptrsKeys_0[] = { &k_00, &k_01, &k_02, &k_03, &k_04, &k_05 }; | |||||
Row_IOE row_0(rowPort1, 1<<0, colPort0, ptrsKeys_0); | |||||
Number of pins in colPort0 should equal number of keys in ptrsKeys_0[] array. | |||||
if a pin is missing, a key will be unresposive | |||||
if a Key pointer is missing, the keyboard will fail in an unprdictable way | |||||
*/ | |||||
class Row_IOE : public RowBase | |||||
{ | |||||
private: | |||||
RowScanner_PinsBitwise scanner; | |||||
Debouncer_4Samples debouncer; | |||||
public: | |||||
Row_IOE( RowPort& refRowPort, const uint8_t strobePin, | |||||
ColPort& refColPort, Key *const ptrsKeys[], const uint8_t KEY_COUNT) //todo if KEY_COUNT is passed in, store it in private | |||||
: RowBase(ptrsKeys), scanner(refRowPort, strobePin, refColPort) { } | |||||
void process(); | |||||
uint8_t getRowState(ColPort* ptrColPort, uint8_t& KEY_COUNT); | |||||
}; | |||||
#endif |