PortRead_MCP23S17::begin() is not needed because port direction is already configured to input by default. | PortRead_MCP23S17::begin() is not needed because port direction is already configured to input by default. | ||||
SPI bus is configured in PortWrite_MCP23S17::begin(). | SPI bus is configured in PortWrite_MCP23S17::begin(). | ||||
*/ | */ | ||||
void PortRead_MCP23S17::begin() | |||||
void PortRead_MCP23S17::begin(const uint8_t strobeOn) | |||||
{ | { | ||||
uint8_t pullUp; //bitwise, 1 means internal pull-up resistor enabled | |||||
if (strobeOn == LOW) //if active low | |||||
{ | |||||
pullUp = readPins; | |||||
} | |||||
else | |||||
{ | |||||
pullUp = 0; | |||||
} | |||||
pinMode(SS, OUTPUT); //configure controller's Slave Select pin to output | pinMode(SS, OUTPUT); //configure controller's Slave Select pin to output | ||||
digitalWrite(SS, HIGH); //disable Slave Select | digitalWrite(SS, HIGH); //disable Slave Select | ||||
SPI.begin(); | SPI.begin(); | ||||
SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //control SPI bus todo is slow clock needed? | SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //control SPI bus todo is slow clock needed? | ||||
digitalWrite(SS, LOW); //enable Slave Select | |||||
digitalWrite(SS, LOW); //enable Slave Select | |||||
SPI.transfer(port.ADDR << 1); //write command | SPI.transfer(port.ADDR << 1); //write command | ||||
SPI.transfer(port.num); //configure IODIR | SPI.transfer(port.num); //configure IODIR | ||||
SPI.transfer(pullUp); //0=output (for LED), 1=input (for read) | |||||
SPI.transfer(readPins); //0=output (for LED), 1=input (for read) | |||||
digitalWrite(SS, LOW); //enable Slave Select | digitalWrite(SS, LOW); //enable Slave Select | ||||
digitalWrite(SS, HIGH); //disable Slave Select | |||||
digitalWrite(SS, HIGH); //disable Slave Select | |||||
SPI.transfer(port.ADDR << 1); //write command | SPI.transfer(port.ADDR << 1); //write command | ||||
SPI.transfer(port.num + 0x0C); //configure GPPU | SPI.transfer(port.num + 0x0C); //configure GPPU | ||||
SPI.transfer(pullUp); //0=pull-up disabled (for LED), 1=pull-up enabled (for read) | SPI.transfer(pullUp); //0=pull-up disabled (for LED), 1=pull-up enabled (for read) | ||||
digitalWrite(SS, HIGH); //disable Slave Select | digitalWrite(SS, HIGH); //disable Slave Select | ||||
//SPI.endTransaction() is not called to release the SPI bus | //SPI.endTransaction() is not called to release the SPI bus | ||||
// because keyboard only has one SPI device. | // because keyboard only has one SPI device. | ||||
} | } |
#include <SPI.h> | #include <SPI.h> | ||||
#include <PortRead.h> | #include <PortRead.h> | ||||
#include "PortIOE.h" | #include "PortIOE.h" | ||||
#include "Scanner_Port.h" | |||||
/* One MCP23S17 I/O expander port connected to matrix columns. | /* One MCP23S17 I/O expander port connected to matrix columns. | ||||
Instantiation todo | Instantiation todo | ||||
------------ | ------------ | ||||
pullUp parameter is port's bitwise pin configuration | |||||
readPins parameter is port's bitwise pin configuration | |||||
1=configure as input (for pins connected to column) | 1=configure as input (for pins connected to column) | ||||
0=configure as output (for LED or not connected to a column) | 0=configure as output (for LED or not connected to a column) | ||||
PortIOE port1(1, 0); | PortIOE port1(1, 0); | ||||
PortRead_MCP23S17 colPort1(port1, 2<<0 | 1<<3 ); | PortRead_MCP23S17 colPort1(port1, 2<<0 | 1<<3 ); | ||||
pullUp are read from pin 0 on up. | |||||
readPins are read from pin 0 on up. | |||||
*/ | */ | ||||
class PortRead_MCP23S17 : public PortRead | class PortRead_MCP23S17 : public PortRead | ||||
{ | { | ||||
private: | private: | ||||
PortIOE& port; | PortIOE& port; | ||||
const uint8_t pullUp; //bitwise, 1 means internal pull-up resistor enabled | |||||
const uint8_t readPins; //bitwise, 1 means internal pull-up resistor enabled | |||||
public: | public: | ||||
PortRead_MCP23S17(PortIOE& port, const uint8_t pullUp) : port(port), pullUp(pullUp) {} | |||||
void begin(); | |||||
PortRead_MCP23S17(PortIOE& port, const uint8_t readPins) : port(port), readPins(readPins) {} | |||||
void begin(const uint8_t strobeOn); | |||||
virtual uint8_t read(); | virtual uint8_t read(); | ||||
}; | }; | ||||
#endif | #endif |
} | } | ||||
/* | /* | ||||
pin is bitwise, where pin being strobed is 1. | |||||
strobe is HIGH or LOW (for active high or active low). | |||||
strobePin is bitwise, where pin being strobed is 1. | |||||
pinLogicLevel is HIGH or LOW. | |||||
port.outputVal can be shared by LEDs. | port.outputVal can be shared by LEDs. | ||||
The functions does not reset the other pins so that they can be used for LEDs. | The functions does not reset the other pins so that they can be used for LEDs. | ||||
*/ | */ | ||||
void PortWrite_MCP23S17::write(const uint8_t pin, const bool strobe) | |||||
void PortWrite_MCP23S17::write(const uint8_t strobePin, const uint8_t pinLogicLevel) | |||||
{ | { | ||||
if (strobe == LOW) //if active low | |||||
if (pinLogicLevel == LOW) | |||||
{ | { | ||||
port.outputVal &= ~pin; //set pin output to low | |||||
port.outputVal &= ~strobePin; //set strobePin output to low | |||||
} | } | ||||
else //if active high | |||||
else | |||||
{ | { | ||||
port.outputVal |= pin; //set pin output to high | |||||
port.outputVal |= strobePin; //set strobePin output to high | |||||
} | } | ||||
writePort(port.num + 0x12, port.outputVal); //set GPIO port pins for stobe and LEDs | writePort(port.num + 0x12, port.outputVal); //set GPIO port pins for stobe and LEDs |
public: | public: | ||||
PortWrite_MCP23S17(PortIOE& port) : port(port) {} | PortWrite_MCP23S17(PortIOE& port) : port(port) {} | ||||
void begin(); | void begin(); | ||||
virtual void write(const uint8_t pin, const bool level); | |||||
virtual void write(const uint8_t pin, const uint8_t level); | |||||
}; | }; | ||||
#endif | #endif |
*/ | */ | ||||
#include "PortIOE.h" | #include "PortIOE.h" | ||||
#include "PortRead_MCP23S17.h" | #include "PortRead_MCP23S17.h" | ||||
#include "Scanner_Port.h" | |||||
const bool Scanner_Port::STROBE_ON = LOW; | |||||
const bool Scanner_Port::STROBE_OFF = HIGH; | |||||
const uint8_t PortIOE::ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded | const uint8_t PortIOE::ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded | ||||
PortIOE portB(1, 0); | PortIOE portB(1, 0); |