diff --git a/doc/keybrd_library_developer_guide.md b/doc/keybrd_library_developer_guide.md index 4506c49..27d90ef 100644 --- a/doc/keybrd_library_developer_guide.md +++ b/doc/keybrd_library_developer_guide.md @@ -186,6 +186,8 @@ Most derived-class names start with the base class name followed by "_" and a na This convention leads to class names that convey information about the classes inheritance. Underscore delineates base class name and sub-class name. Capital letters delineate words. +Interface class names end with "Interface". + Layer-class naming conventions ------------------------------ Layer classes are explained in [tutorial_3a_multi-layer_keyboard.md](../tutorials/tutorial_3a_multi-layer_keyboard.md). diff --git a/src/PortRead_MCP23S17.cpp b/src/PortRead_MCP23S17.cpp index 199bd64..83fb56c 100644 --- a/src/PortRead_MCP23S17.cpp +++ b/src/PortRead_MCP23S17.cpp @@ -4,20 +4,42 @@ PortRead_MCP23S17::begin() is not needed because port direction is already configured to input by default. SPI bus is configured in PortWrite_MCP23S17::begin(). */ +void PortRead_MCP23S17::begin() +{ + pinMode(SS, OUTPUT); //configure controller's Slave Select pin to output + digitalWrite(SS, HIGH); //disable Slave Select + SPI.begin(); + SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //control SPI bus todo is slow clock needed? + digitalWrite(SS, LOW); //enable Slave Select + + SPI.transfer(port.ADDR << 1); //write command + SPI.transfer(port.num); //configure IODIR + SPI.transfer(pullUp); //0=output (for LED), 1=input (for read) + + digitalWrite(SS, LOW); //enable Slave Select + digitalWrite(SS, HIGH); //disable Slave Select + + SPI.transfer(port.ADDR << 1); //write command + SPI.transfer(port.num + 0x0C); //configure GPPU + SPI.transfer(pullUp); //0=pull-up disabled (for LED), 1=pull-up enabled (for read) + + digitalWrite(SS, HIGH); //disable Slave Select + //SPI.endTransaction() is not called to release the SPI bus + // because keyboard only has one SPI device. +} /* -returns port value +read() returns portState. */ uint8_t PortRead_MCP23S17::read() { - uint8_t portState; //bit wise + uint8_t portState; //bit wise - //slower clock - digitalWrite(SS, LOW); //enable Slave Select - SPI.transfer(port.ADDR << 1 | 1); //read command - SPI.transfer(port.num + 0x12); //register address to read data from - portState = SPI.transfer(0); //save the data (0 is dummy data to send) - digitalWrite(SS, HIGH); //disable Slave Select + digitalWrite(SS, LOW); //enable Slave Select + SPI.transfer(port.ADDR << 1 | 1); //read command + SPI.transfer(port.num + 0x12); //GPIO register address to read data from + portState = SPI.transfer(0); //save the data (0 is dummy data to send) + digitalWrite(SS, HIGH); //disable Slave Select return portState; } diff --git a/src/PortRead_MCP23S17.h b/src/PortRead_MCP23S17.h index 830615d..87e1ac1 100644 --- a/src/PortRead_MCP23S17.h +++ b/src/PortRead_MCP23S17.h @@ -7,11 +7,10 @@ #include "PortIOE.h" /* One MCP23S17 I/O expander port connected to matrix columns. -MCP23S17 does not have internal pull-up resistors (PCA9535E does). -Instantiation +Instantiation todo ------------ -readPins parameter is port's bitwise pin configuration +pullUp parameter is port's bitwise pin configuration 1=configure as input (for pins connected to column) 0=configure as output (for LED or not connected to a column) @@ -22,18 +21,17 @@ Example instantiation for column port 1, with pins 2 and 3 connected to columns: PortIOE port1(1, 0); PortRead_MCP23S17 colPort1(port1, 2<<0 | 1<<3 ); -readPins are read from pin 0 on up. +pullUp are read from pin 0 on up. */ class PortRead_MCP23S17 : public PortRead { private: PortIOE& port; + const uint8_t pullUp; //bitwise, 1 means internal pull-up resistor enabled public: -/* -*/ - //The constructor initialization list is in .cpp - PortRead_MCP23S17(PortIOE& port) : port(port) {} + PortRead_MCP23S17(PortIOE& port, const uint8_t pullUp) : port(port), pullUp(pullUp) {} + void begin(); virtual uint8_t read(); }; #endif diff --git a/src/PortWrite_MCP23S17.cpp b/src/PortWrite_MCP23S17.cpp index 73fd1c5..f11ea99 100644 --- a/src/PortWrite_MCP23S17.cpp +++ b/src/PortWrite_MCP23S17.cpp @@ -1,32 +1,31 @@ #include "PortWrite_MCP23S17.h" +/* writePort() sets registerAddr to data. +*/ void PortWrite_MCP23S17::writePort(const uint8_t registerAddr, const uint8_t data) { - //slower clock - //SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //control SPI bus todo move to begin() - digitalWrite(SS, LOW); //enable Slave Select - SPI.transfer(port.ADDR << 1); //write command - SPI.transfer(registerAddr); //register address to write data to - SPI.transfer(data); //data - digitalWrite(SS, HIGH); //disable Slave Select - //SPI.endTransaction(); //release the SPI bus + digitalWrite(SS, LOW); //enable Slave Select + SPI.transfer(port.ADDR << 1); //write command + SPI.transfer(registerAddr); //register address to write data to + SPI.transfer(data); //data + digitalWrite(SS, HIGH); //disable Slave Select } -/* -If PortRead_MCP23S17 is instantiated on the same port, do NOT use PortWrite_MCP23S17::begin(). -Otherwise readPins could be overwritten. +/* begin() should be called once from sketch in setup(). +PortRead_MCP23S17 and PortWrite_MCP23S17 should be on seperate ports on the same MCP23S17. Output pins can be used for strobe pins and LEDs. - -SPI.endTransaction() is not called because keyboard only has one SPI device, so no need to release the SPI bus */ void PortWrite_MCP23S17::begin() { - pinMode(SS, OUTPUT); //configure controller's Slave Select pin to output - digitalWrite(SS, HIGH); //disable Slave Select + pinMode(SS, OUTPUT); //configure controller's Slave Select pin to output + digitalWrite(SS, HIGH); //disable Slave Select SPI.begin(); - SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //control SPI bus + SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //control SPI bus todo is slow clock needed? - writePort(port.num, 0); //configure port direction (port.num) to output (0) + writePort(port.num, 0); //configure port direction (port.num) to output (0) + + //SPI.endTransaction() is not called to release the SPI bus + // because keyboard only has one SPI device. } /* diff --git a/tutorials/tutorial_10_writing_IOE_Port_classes.md b/tutorials/tutorial_10_writing_IOE_Port_classes.md index c3304dc..d2e98c6 100644 --- a/tutorials/tutorial_10_writing_IOE_Port_classes.md +++ b/tutorials/tutorial_10_writing_IOE_Port_classes.md @@ -16,7 +16,7 @@ To write a new Port class: Write very simple read and write examples for your I/O expander. Simple SPI I/O expander examples: todo link, pictures - /home/wolfv/Documents/Arduino/demo/IOE_MCP23S17_read/ + /home/wolfv/Documents/Arduino/demo/IOE_MCP23S17_read/ todo internal pull-up resistors /home/wolfv/Documents/Arduino/demo/IOE_MCP23S17_write/ Simple I2C I/O expander examples: todo link, pictures diff --git a/unit_tests/PortRead_MCP23S17/PortRead_MCP23S17.ino b/unit_tests/PortRead_MCP23S17/PortRead_MCP23S17.ino index dd84376..887129b 100644 --- a/unit_tests/PortRead_MCP23S17/PortRead_MCP23S17.ino +++ b/unit_tests/PortRead_MCP23S17/PortRead_MCP23S17.ino @@ -9,24 +9,22 @@ http://arduino.stackexchange.com/questions/28792/reading-an-mcp23s17-i-o-expande */ #include "PortIOE.h" #include "PortRead_MCP23S17.h" -#include "PortWrite_MCP23S17.h" const uint8_t PortIOE::ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded PortIOE portB(1, 0); -PortRead_MCP23S17 portBRead(portB); -PortWrite_MCP23S17 portBWrite(portB); //PortBWrite needed for begin() +PortRead_MCP23S17 portBRead(portB, ~0); void setup() { uint8_t portBState; //bit wise delay(6000); - portBWrite.begin(); + portBRead.begin(); portBState = portBRead.read(); Keyboard.print("portBState = "); - Keyboard.println(portBState, BIN); //should print 10101010 + Keyboard.println(portBState, BIN); //prints 10101010 } void loop() { }