SPI.begin(); | SPI.begin(); | ||||
SPI.beginTransaction( SPISettings(5000000, MSBFIRST, SPI_MODE0) ); //control SPI bus, 5 MHz | SPI.beginTransaction( SPISettings(5000000, MSBFIRST, SPI_MODE0) ); //control SPI bus, 5 MHz | ||||
//SPI.endTransaction() not called to release SPI bus because keyboard only has one SPI device | //SPI.endTransaction() not called to release SPI bus because keyboard only has one SPI device | ||||
//if two IOEs are used, move beginTransaction() endTransaction() to write() read() functions | |||||
} | } | ||||
/* begin() is called from Scanner_IOE::begin(). | /* begin() is called from Scanner_IOE::begin(). | ||||
pullUp = 0; | pullUp = 0; | ||||
} | } | ||||
transfer(DEVICE_ADDR << 1, portNum, readPins); //configure IODIR | |||||
transfer(DEVICE_ADDR << 1, portNum + 0x0C, pullUp); //configure GPPU | |||||
transfer(deviceAddr << 1, portNum, readPins); //configure IODIR | |||||
transfer(deviceAddr << 1, portNum + 0x0C, pullUp); //configure GPPU | |||||
} | } | ||||
/* write() sets pin output to logicLevel (useful for strobePin, one LED pin, or multiple pins). | /* write() sets pin output to logicLevel (useful for strobePin, one LED pin, or multiple pins). | ||||
outputVal |= pin; //set pin output to high | outputVal |= pin; //set pin output to high | ||||
} | } | ||||
transfer(DEVICE_ADDR << 1, portNum + 0x12, outputVal); //set GPIO port to outputVal | |||||
transfer(deviceAddr << 1, portNum + 0x12, outputVal); //set GPIO port to outputVal | |||||
} | } | ||||
/* read() returns portState. Only portState pins with pull resistors are valid. | /* read() returns portState. Only portState pins with pull resistors are valid. | ||||
*/ | */ | ||||
uint8_t PortMCP23S17::read() | uint8_t PortMCP23S17::read() | ||||
{ | { | ||||
return transfer( (DEVICE_ADDR << 1) | 1, portNum + 0x12, 0); //read from GPIO | |||||
return transfer( (deviceAddr << 1) | 1, portNum + 0x12, 0); //read from GPIO | |||||
} | } |
class PortMCP23S17 : public PortInterface | class PortMCP23S17 : public PortInterface | ||||
{ | { | ||||
private: | private: | ||||
static const uint8_t DEVICE_ADDR; | |||||
const uint8_t deviceAddr; | |||||
const uint8_t portNum; //port identification number | const uint8_t portNum; //port identification number | ||||
uint8_t outputVal; //bit pattern for strobe and LEDs | uint8_t outputVal; //bit pattern for strobe and LEDs | ||||
const uint8_t readPins; //bits, IODIR 0=output, 1=input | const uint8_t readPins; //bits, IODIR 0=output, 1=input | ||||
uint8_t transfer(const uint8_t command, const uint8_t registerAddr, const uint8_t data); | uint8_t transfer(const uint8_t command, const uint8_t registerAddr, const uint8_t data); | ||||
public: | public: | ||||
PortMCP23S17(const uint8_t portNum, const uint8_t readPins) | |||||
: portNum(portNum), outputVal(0), readPins(readPins) {} | |||||
PortMCP23S17(const uint8_t deviceAddr, const uint8_t portNum, const uint8_t readPins) | |||||
: deviceAddr(deviceAddr), portNum(portNum), outputVal(0), readPins(readPins) {} | |||||
void beginProtocol(); | void beginProtocol(); | ||||
void begin(const uint8_t strobeOn); | void begin(const uint8_t strobeOn); | ||||
virtual void write(const uint8_t pin, const bool logicLevel); | virtual void write(const uint8_t pin, const bool logicLevel); |
// =============== RIGHT =============== | // =============== RIGHT =============== | ||||
// --------------- RIGHT SCANNER --------------- | // --------------- RIGHT SCANNER --------------- | ||||
const uint8_t PortMCP23S17::DEVICE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded | |||||
PortMCP23S17 portA(0, 1<<0 | 1<<1 ); //for read and LED | |||||
PortMCP23S17 portB(1, 0); //for strobe and LED | |||||
const uint8_t IOE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded | |||||
PortMCP23S17 portA(IOE_ADDR, 0, 1<<0 | 1<<1 ); //for read and LED | |||||
PortMCP23S17 portB(IOE_ADDR, 1, 0); //for strobe and LED | |||||
Scanner_IOE scanner_R(LOW, portB, portA); | Scanner_IOE scanner_R(LOW, portB, portA); | ||||