@@ -10,39 +10,37 @@ | |||
// ================= INCLUDES ================== | |||
#include <ScanDelay.h> | |||
#include <Code_Sc.h> | |||
#include <Row.h> | |||
//left matrix | |||
#include <Row_uC.h> | |||
#include <Scanner_uC.h> | |||
//right matrix | |||
#include <Row_IOE.h> | |||
#include <PortIOE.h> | |||
#include <PortWrite_PCA9655E.h> | |||
#include <PortRead_PCA9655E.h> | |||
#include <Scanner_IOE.h> | |||
// ============ SPEED CONFIGURATION ============ | |||
ScanDelay scanDelay(9000); | |||
// =============== LEFT uC MATRIX ============== | |||
const bool Scanner_uC::STROBE_ON = HIGH; //active high | |||
const bool Scanner_uC::STROBE_OFF = LOW; | |||
// ================ LEFT SCANNER =============== | |||
uint8_t readPins_L[] = {0, 1}; | |||
uint8_t readPinCount_L = sizeof(readPins_L)/sizeof(*readPins_L); | |||
// ============== RIGHT IOE MATRIX ============= | |||
const bool Scanner_Port::STROBE_ON = HIGH; //active high | |||
const bool Scanner_Port::STROBE_OFF = LOW; | |||
Scanner_uC scanner_L(HIGH, readPins_L, readPinCount_L); | |||
// =============== RIGHT SCANNER =============== | |||
const uint8_t PortIOE::DEVICE_ADDR = 0x18; | |||
// ------------------ PORT 1 ------------------- | |||
PortIOE port1_R(1, 0); | |||
PortWrite_PCA9655E portWrite1_R(port1_R); | |||
PortIOE port_R1(1, 0); | |||
PortWrite_PCA9655E portWrite_R1(port_R1); | |||
PortIOE port_R0(0, 0); | |||
//PortWrite_PCA9655E portWrite_R0(port_R0); for LEDs | |||
PortRead_PCA9655E portRead_R0(port_R0, 1<<0 | 1<<1 ); | |||
// ------------------ PORT 0 ------------------- | |||
PortIOE port0_R(0, 0); | |||
PortWrite_PCA9655E portWrite0_R(port0_R); | |||
PortRead_PCA9655E portRead0_R(port0_R, 1<<0 | 1<<1 ); | |||
Scanner_IOE scanner_R(HIGH, portWrite_R1, portRead_R0); | |||
// =================== CODES =================== | |||
Code_Sc s_a(KEY_A); | |||
@@ -59,28 +57,26 @@ Code_Sc s_4(KEY_4); | |||
// ---------------- LEFT ROWS ------------------ | |||
Key* ptrsKeys_L0[] = { &s_1, &s_2 }; | |||
uint8_t KEY_COUNT_L0 = sizeof(ptrsKeys_L0)/sizeof(*ptrsKeys_L0); | |||
Row_uC row_L0(21, readPins_L, KEY_COUNT_L0, ptrsKeys_L0); | |||
Row row_L0(scanner_L, 21, ptrsKeys_L0, KEY_COUNT_L0); | |||
Key* ptrsKeys_L1[] = { &s_a, &s_b }; | |||
uint8_t KEY_COUNT_L1 = sizeof(ptrsKeys_L1)/sizeof(*ptrsKeys_L1); | |||
Row_uC row_L1(20, readPins_L, KEY_COUNT_L1, ptrsKeys_L1); | |||
Row row_L1(scanner_L, 20, ptrsKeys_L1, KEY_COUNT_L1); | |||
// ---------------- RIGHT ROWS ----------------- | |||
Key* ptrsKeys_R0[] = { &s_3, &s_4 }; | |||
uint8_t KEY_COUNT_R0 = sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0); | |||
Row_IOE row_R0(portWrite1_R, 1<<0, portRead0_R, KEY_COUNT_R0, ptrsKeys_R0); | |||
Row row_R0(scanner_R, 1<<0, ptrsKeys_R0, KEY_COUNT_R0); | |||
Key* ptrsKeys_R1[] = { &s_c, &s_d }; | |||
uint8_t KEY_COUNT_R1 = sizeof(ptrsKeys_R1)/sizeof(*ptrsKeys_R1); | |||
Row_IOE row_R1(portWrite1_R, 1<<1, portRead0_R, KEY_COUNT_R1, ptrsKeys_R1); | |||
Row row_R1(scanner_R, 1<<1, ptrsKeys_R1, KEY_COUNT_R1); | |||
// ################### MAIN #################### | |||
void setup() | |||
{ | |||
Keyboard.begin(); | |||
Wire.begin(); //Wire.begin() must be called before port begin() | |||
portWrite1_R.begin(); | |||
portRead0_R.begin(); | |||
scanner_R.begin(); | |||
} | |||
void loop() |
@@ -12,6 +12,7 @@ Details are in config_key.h | |||
class PortReadInterface | |||
{ | |||
public: | |||
virtual void begin()=0; | |||
virtual uint8_t read()=0; | |||
}; | |||
#endif |
@@ -5,7 +5,7 @@ | |||
#include <SPI.h> | |||
#include <PortReadInterface.h> | |||
#include "PortIOE.h" | |||
#include "Scanner_Port.h" | |||
#include "Scanner_IOE.h" | |||
/* One MCP23S17 I/O expander port connected to matrix columns. | |||
@@ -12,6 +12,7 @@ Details are in config_key.h | |||
class PortWriteInterface | |||
{ | |||
public: | |||
virtual void begin()=0; | |||
virtual void write(const uint8_t pin, const bool level)=0; | |||
}; | |||
#endif |
@@ -1,13 +1,14 @@ | |||
#include "Row.h" | |||
/* constructor | |||
init() is called once for each row. | |||
*/ | |||
Row::Row(ScannerInterface& refScanner, const uint8_t strobePin, | |||
Key* const ptrsKeys[], const uint8_t readPinCount) | |||
: refScanner(refScanner), strobePin(strobePin), | |||
ptrsKeys(ptrsKeys), readPinCount(readPinCount), debounced(0) | |||
{ | |||
refScanner.begin(strobePin); | |||
refScanner.init(strobePin); | |||
} | |||
/* process() scans the row and calls any newly pressed or released keys. |
@@ -8,7 +8,7 @@ | |||
class ScannerInterface | |||
{ | |||
public: | |||
virtual void begin(const uint8_t strobePin)=0; | |||
virtual void init(const uint8_t strobePin)=0; | |||
virtual read_pins_t scan(const uint8_t strobePin)=0; | |||
}; | |||
#endif |
@@ -0,0 +1,37 @@ | |||
#include "Scanner_IOE.h" | |||
/* Row constructor calls every Scanner's init(). | |||
*/ | |||
void Scanner_IOE::init(const uint8_t strobePin) | |||
{ | |||
//emty function | |||
} | |||
/* begin() should be called once from sketch setup(). | |||
*/ | |||
void Scanner_IOE::begin() | |||
{ | |||
Wire.begin(); | |||
refPortWrite.begin(); | |||
refPortRead.begin(); | |||
} | |||
/* scan() strobes the row's strobePin and retuns state of port's input pins. | |||
Bitwise variables are 1 bit per key. | |||
*/ | |||
uint8_t Scanner_IOE::scan(const uint8_t strobePin) | |||
{ | |||
uint8_t readState; //bitwise, 1 means key is pressed, 0 means released | |||
//strobe on | |||
refPortWrite.write(strobePin, strobeOn); | |||
delayMicroseconds(3); //time to stabilize voltage | |||
//read the port pins | |||
readState = refPortRead.read(); | |||
//strobe off | |||
refPortWrite.write(strobePin, strobeOff); | |||
return readState; | |||
} |
@@ -0,0 +1,33 @@ | |||
#ifndef SCANNER_PORT_H | |||
#define SCANNER_PORT_H | |||
#include <Arduino.h> | |||
#include <inttypes.h> | |||
#include <Wire.h> | |||
#include <ScannerInterface.h> | |||
#include <PortWriteInterface.h> | |||
#include <PortReadInterface.h> | |||
/* Scanner_IOE uses bit manipulation to read all pins of one port. | |||
The ports are normally from an I/O Expander, but could also be ports from an AVR uC. | |||
The maximum keys per row is 8, because ports have a maximum of 8 pins each. | |||
keybrd_library_developer_guide.md has instructions for ## Active state and diode orientation | |||
*/ | |||
class Scanner_IOE : public ScannerInterface | |||
{ | |||
private: | |||
const bool strobeOn; //logic level of strobe on, HIGH or LOW | |||
const bool strobeOff; //logic level of strobe off, complement of strobeOn | |||
PortWriteInterface& refPortWrite; //the IC port containing the strobePin | |||
PortReadInterface& refPortRead; //the IC's read port | |||
public: | |||
Scanner_IOE(const bool strobeOn, | |||
PortWriteInterface &refPortWrite, PortReadInterface& refPortRead) | |||
: strobeOn(strobeOn), strobeOff(!strobeOn), | |||
refPortWrite(refPortWrite), refPortRead(refPortRead) {} | |||
void init(const uint8_t strobePin); | |||
void begin(); | |||
uint8_t scan(const uint8_t strobePin); | |||
}; | |||
#endif |
@@ -1,21 +0,0 @@ | |||
#include "Scanner_Port.h" | |||
/* scan() strobes the row's strobePin and retuns state of port's input pins. | |||
Bitwise variables are 1 bit per key. | |||
*/ | |||
uint8_t Scanner_Port::scan(const uint8_t strobePin) | |||
{ | |||
uint8_t readState; //bitwise, 1 means key is pressed, 0 means released | |||
//strobe on | |||
refPortWrite.write(strobePin, STROBE_ON); | |||
delayMicroseconds(3); //time to stabilize voltage | |||
//read the port pins | |||
readState = refPortRead.read(); | |||
//strobe off | |||
refPortWrite.write(strobePin, STROBE_OFF); | |||
return readState; | |||
} |
@@ -1,27 +0,0 @@ | |||
#ifndef SCANNER_PORT_H | |||
#define SCANNER_PORT_H | |||
#include <Arduino.h> | |||
#include <inttypes.h> | |||
#include <PortWriteInterface.h> | |||
#include <PortReadInterface.h> | |||
/* Scanner_Port uses bit manipulation to read all pins of one port. | |||
The ports are normally from an I/O Expander, but could also be ports from an AVR uC. | |||
The maximum keys per row is 8, because ports have a maximum of 8 pins each. | |||
keybrd_library_developer_guide.md has instructions for ## Active state and diode orientation | |||
*/ | |||
class Scanner_Port | |||
{ | |||
private: | |||
static const bool STROBE_ON; //HIGH or LOW logic level of strobe on, active state | |||
static const bool STROBE_OFF; //logic level of strobe off, complement of STROBE_ON | |||
PortWriteInterface& refPortWrite; //the IC port containing the strobePin | |||
PortReadInterface& refPortRead; //the IC's read port | |||
public: | |||
Scanner_Port(PortWriteInterface &refPortWrite, PortReadInterface& refPortRead) | |||
: refPortWrite(refPortWrite), refPortRead(refPortRead) {} | |||
uint8_t scan(const uint8_t strobePin); | |||
}; | |||
#endif |
@@ -31,10 +31,10 @@ Scanner_uC::Scanner_uC(const bool strobeOn, const uint8_t readPins[], const uint | |||
} | |||
} | |||
/* | |||
/* init() is called once for each row from Row constructor. | |||
Configure row-strobe pin to output. | |||
*/ | |||
void Scanner_uC::begin(const uint8_t strobePin) | |||
void Scanner_uC::init(const uint8_t strobePin) | |||
{ | |||
pinMode(strobePin, OUTPUT); | |||
} |
@@ -5,8 +5,6 @@ | |||
#include <inttypes.h> | |||
#include <config_keybrd.h> | |||
#include <ScannerInterface.h> | |||
//#include <PortWriteInterface.h>todo not needed? | |||
//#include <PortReadInterface.h> | |||
/* Scanner_uC class uses Arduino pin numbers (not port pin numbers). | |||
Limit number of readPins to size of read_pins_t, which is defined in config_keybrd.h | |||
@@ -20,7 +18,7 @@ class Scanner_uC : public ScannerInterface | |||
const uint8_t readPinCount; //number of readPins | |||
public: | |||
Scanner_uC(const bool strobeOn, const uint8_t readPins[], const uint8_t readPinCount); | |||
void begin(const uint8_t strobePin); | |||
void init(const uint8_t strobePin); | |||
virtual read_pins_t scan(const uint8_t strobePin); | |||
}; | |||
#endif |
@@ -11,7 +11,7 @@ Using smaller types on a 32-bit uC (Teensy LC) would accomplish nothing. | |||
/* Use a read_pins_t size that covers all read pins of all RowScanner objects i.e. | |||
For Scanner_uC, Scanner_uC::readPinCount | |||
For Scanner_ShiftRegs74HC165, Scanner_ShiftRegs74HC165::readPinCount | |||
For Scanner_Port, cover the last 1 bit in Scanner_Port::strobePin | |||
For Scanner_IOE, cover the last 1 bit in Scanner_IOE::strobePin | |||
*/ | |||
typedef uint8_t read_pins_t; | |||
//typedef uint16_t read_pins_t; |
@@ -7,10 +7,10 @@ | |||
*/ | |||
// ################## GLOBAL ################### | |||
// ================= INCLUDES ================== | |||
#include <Scanner_uC.h> | |||
#include <ScanDelay.h> | |||
#include <Code_Sc.h> | |||
#include <Row.h> | |||
#include <Scanner_uC.h> | |||
// ============ SPEED CONFIGURATION ============ | |||
ScanDelay scanDelay(9000); |