diff --git a/src/PortMCP23S17.cpp b/src/PortMCP23S17.cpp index c8f0919..3ef7197 100644 --- a/src/PortMCP23S17.cpp +++ b/src/PortMCP23S17.cpp @@ -1,36 +1,34 @@ #include "PortMCP23S17.h" /* transfer() writes data to registerAddr, reads portSate from registerAddr, and returns portState. + +MCP23S17 SPI interface is 10 MHz max. +The electrical limitation to bus speed is bus capacitance and the length of the wires involved. +Longer wires require lower clock speeds. */ uint8_t PortMCP23S17::transfer(const uint8_t command, const uint8_t registerAddr, const uint8_t data) { uint8_t portState; //bit pattern + SPI.beginTransaction( SPISettings(5000000, MSBFIRST, SPI_MODE0) ); //control SPI bus, 5 MHz digitalWrite(SS, LOW); //enable Slave Select SPI.transfer(command); //write or read command SPI.transfer(registerAddr); //register address to write data to portState = SPI.transfer(data); //write data, read portState digitalWrite(SS, HIGH); //disable Slave Select + SPI.endTransaction(); return portState; } -/* begin() is called from Scanner_IOE::begin(). -Initiates SPI bus and configures I/O pins for read and write. - -MCP23S17 SPI interface is 10 MHz max. -The electrical limitation to bus speed is bus capacitance and the length of the wires involved. -Longer wires require lower clock speeds. +/* begin() is called from Scanner_IOE::begin(). Initiates SPI bus. */ void PortMCP23S17::beginProtocol() { pinMode(SS, OUTPUT); //configure controller's Slave Select pin to output digitalWrite(SS, HIGH); //disable Slave Select SPI.begin(); - 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 - //if two IOEs are used, move beginTransaction() endTransaction() to write() read() functions } /* begin() is called from Scanner_IOE::begin(). diff --git a/src/PortMCP23S17.h b/src/PortMCP23S17.h index 0a5ad80..3b1467e 100644 --- a/src/PortMCP23S17.h +++ b/src/PortMCP23S17.h @@ -6,8 +6,8 @@ #include /* -readPins are connected to matrix col -write pin is connected to matrix Row (strobe pin) or LED. +write pins are connected to matrix Row (strobe pin) or LED. +readPins are connected to matrix column to read which keys are pressed. Slave Select is hardcoded to Arduino Pin 10. Arduino Pin 10 avoids the speed penalty of digitalWrite. @@ -20,9 +20,9 @@ MCP23S17 datasheet identifies ports by letters, while class PortMCP23S17 uses po readPins parameter configures port's pins. Example instantiation: - const uint8_t Port_MCP23S17::DEVICE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins grounded - Port_MCP23S17 portB(1, 0); //all pins are set to output for strobes and LEDs - Port_MCP23S17 portA(0, 1<<0 | 1<<1 ); //1 pins are set to input for reading, + const uint8_t IOE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded + Port_MCP23S17 portB(IOE_ADDR, 1, 0); //all pins are set to output for strobes and LEDs + Port_MCP23S17 portA(IOE_ADDR, 0, 1<<0 | 1<<1 ); //first two pins are set to input for reading, //remaining pins can be used for LEDs Diode orientation @@ -39,7 +39,7 @@ class PortMCP23S17 : public PortInterface const uint8_t deviceAddr; const uint8_t portNum; //port identification number uint8_t outputVal; //bit pattern for strobe and LEDs - const uint8_t readPins; //bits, IODIR 0=output, 1=input + const uint8_t readPins; //bit pattern, IODIR 0=output, 1=input uint8_t transfer(const uint8_t command, const uint8_t registerAddr, const uint8_t data); public: PortMCP23S17(const uint8_t deviceAddr, const uint8_t portNum, const uint8_t readPins) diff --git a/tutorials/keybrd_4c_split_keyboard_with_IOE/keybrd_4c_split_keyboard_with_IOE.ino b/tutorials/keybrd_4c_split_keyboard_with_IOE/keybrd_4c_split_keyboard_with_IOE.ino index d504d6d..98cf93a 100644 --- a/tutorials/keybrd_4c_split_keyboard_with_IOE/keybrd_4c_split_keyboard_with_IOE.ino +++ b/tutorials/keybrd_4c_split_keyboard_with_IOE/keybrd_4c_split_keyboard_with_IOE.ino @@ -21,9 +21,7 @@ This layout table shows left and right matrices: #include //right matrix -#include -#include -#include +#include #include // ============ SPEED CONFIGURATION ============ @@ -33,37 +31,28 @@ ScanDelay scanDelay(9000); Left matrix rows work the same as the ones in keybrd_2_single-layer.ino */ uint8_t readPins[] = {14, 15}; -const uint8_t READPIN_COUNT = sizeof(readPins)/sizeof(*readPins); +const uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins); -Scanner_uC scanner_L(LOW, readPins, READPIN_COUNT); +Scanner_uC scanner_L(LOW, readPins, readPinCount); /* =============== RIGHT SCANNER =============== The right matrix is scanned by an I/O expander. - -The I/O expander device address is configured by hardware pins. -DEVICE_ADDR is a static variable of class PortIOE. +The MCP23S17 address is set by grounding or powering pins. */ -const uint8_t PortIOE::DEVICE_ADDR = 0x20; //MCP23S17 address with all 3 ADDR pins are grounded +const uint8_t IOE_ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded /* -port_B stobes the row while port_A reads the colums. - -port_A is assigned port identification number 0. -port_A is assigned to portRead, which reads port_A pins 0 and 1. +Normally all strobe pins are on one port, and all the read pins are on the other port. +In this example, portB stobes the row while portA reads the colums. +PortMCP23S17 constructor parameters are: deviceAddr, portNum, readPins +readPins is a bit pattern, where 0=output, 1=input. +In portA, the first two pins are set to input for reading. "<<" (bit shift left) and "|" (OR) are bitwise operators. Pin numbers to be read are to the right of "1<<" and delimited by "|". */ -PortIOE port_A(0); -PortRead_MCP23S17 portRead(port_A, 1<<0 | 1<<1 ); - -/* -port_B is assigned port identification number 1. -port_B is assigned to portWrite. -*/ -PortIOE port_B(1); -PortWrite_MCP23S17 portWrite(port_B); - -Scanner_IOE scanner_R(LOW, portWrite, portRead); +PortMCP23S17 portA(IOE_ADDR, 0, 1<<0 | 1<<1 ); +PortMCP23S17 portB(IOE_ADDR, 1, 0); +Scanner_IOE scanner_R(LOW, portB, portA); // =================== CODES =================== Code_Sc s_a(KEY_A); diff --git a/tutorials/keybrd_5b_LED_on_IOE/keybrd_5b_LED_on_IOE.ino b/tutorials/keybrd_5b_LED_on_IOE/keybrd_5b_LED_on_IOE.ino index ec82be8..ad34ade 100644 --- a/tutorials/keybrd_5b_LED_on_IOE/keybrd_5b_LED_on_IOE.ino +++ b/tutorials/keybrd_5b_LED_on_IOE/keybrd_5b_LED_on_IOE.ino @@ -34,7 +34,7 @@ This layout table shows left and right matrices: // ============ SPEED CONFIGURATION ============ ScanDelay scanDelay(9000); -// ================ LEFT =============== +// ================= LEFT PINS ================= // ---------------- LEFT SCANNER --------------- uint8_t readPins[] = {14, 15}; const uint8_t readPinCount = sizeof(readPins)/sizeof(*readPins); @@ -44,7 +44,7 @@ Scanner_uC scanner_L(LOW, readPins, readPinCount); // ----------------- LEFT LEDs ----------------- LED_uC LED_CapsLck(21); -// =============== RIGHT =============== +// ================ RIGHT PINS ================= // --------------- RIGHT SCANNER --------------- 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 diff --git a/tutorials/tutorial_4c_split_keyboard_with_IOE.md b/tutorials/tutorial_4c_split_keyboard_with_IOE.md index 2faa291..2329b19 100644 --- a/tutorials/tutorial_4c_split_keyboard_with_IOE.md +++ b/tutorials/tutorial_4c_split_keyboard_with_IOE.md @@ -35,7 +35,8 @@ The MCP23S17 with all address pins grounded has an device address of 0x20. The MCP23S17's /RESET pin is connected to VDD. The MCP23S17 I/O expander has two ports. Each port has eight pins. -Port B is connected to the matrix's rows. Port A is connected to the matrix's columns. +Port B is connected to the matrix's rows. +Port A is connected to the matrix's columns. Building a split keyboard with I/O Expander -------------------------------------------