add MCP23S17 port files
This commit is contained in:
parent
997942555d
commit
caa29dec63
@ -7,8 +7,9 @@ Improvement suggestions
|
|||||||
We need to know what improvements to the keybrd library would help you create your keyboard design.
|
We need to know what improvements to the keybrd library would help you create your keyboard design.
|
||||||
Before requesting an improvement, please check [planned_features list](doc/planned_features.md)
|
Before requesting an improvement, please check [planned_features list](doc/planned_features.md)
|
||||||
|
|
||||||
Submit improvement suggestions to [GitHub issues](https://github.com/wolfv6/Keybrd/issues).
|
Submit improvement suggestions to [GitHub issues](https://github.com/wolfv6/Keybrd/issues)
|
||||||
* The issue title should start with "suggestion:" followed by a descriptive title
|
or [geekhack thread](https://geekhack.org/index.php?topic=83599.0).
|
||||||
|
<!-- * The issue title should start with "suggestion:" followed by a descriptive title -->
|
||||||
* Provide a use case
|
* Provide a use case
|
||||||
* Explain why the improvement is useful
|
* Explain why the improvement is useful
|
||||||
* Site other product examples where this improvement exists
|
* Site other product examples where this improvement exists
|
||||||
@ -16,6 +17,8 @@ Submit improvement suggestions to [GitHub issues](https://github.com/wolfv6/Keyb
|
|||||||
Bug reports
|
Bug reports
|
||||||
-----------
|
-----------
|
||||||
A bug report is the first step in making the keybrd library work the way it's supposed to work.
|
A bug report is the first step in making the keybrd library work the way it's supposed to work.
|
||||||
|
Submit bug reports to [GitHub issues](https://github.com/wolfv6/Keybrd/issues)
|
||||||
|
or [geekhack thread](https://geekhack.org/index.php?topic=83599.0).
|
||||||
|
|
||||||
Please provide enough information so we can reproduce the bug behaviour!
|
Please provide enough information so we can reproduce the bug behaviour!
|
||||||
* Complete sketch (copy & paste, attachment, or a link to the code)
|
* Complete sketch (copy & paste, attachment, or a link to the code)
|
||||||
@ -52,7 +55,7 @@ A healthy project needs the perspective of many people.
|
|||||||
* Documentation - Suggest a clarification, simplification, correction, or other improvement.
|
* Documentation - Suggest a clarification, simplification, correction, or other improvement.
|
||||||
We need the perspective of people new to the project to see these things.
|
We need the perspective of people new to the project to see these things.
|
||||||
Sometimes just changing a word or two makes a big difference.
|
Sometimes just changing a word or two makes a big difference.
|
||||||
* [Current user contributions](https://geekhack.org/index.php?topic=83599.0) highlights contributions that are needed for the keybrd project's current stage of development.
|
* [Current user contributions](https://geekhack.org/index.php?topic=83599.msg2223776#msg2223776) highlights contributions that are needed for the keybrd project's current stage of development.
|
||||||
|
|
||||||
Text file documentation style guide:
|
Text file documentation style guide:
|
||||||
* Use Markdown with a .md suffix.
|
* Use Markdown with a .md suffix.
|
||||||
|
@ -27,7 +27,7 @@ Row_Ext::keyWasPressed() overrides Row::keyWasPressed() which is used to unstick
|
|||||||
|
|
||||||
Row_Ext_uC and Row_Ext_ShiftRegisters are a custom classes composed of stock keybrd library classes.<br>
|
Row_Ext_uC and Row_Ext_ShiftRegisters are a custom classes composed of stock keybrd library classes.<br>
|
||||||
Row_Ext_uC uses Scanner_uC to scan the primary matrix.<br>
|
Row_Ext_uC uses Scanner_uC to scan the primary matrix.<br>
|
||||||
Row_Ext_ShiftRegisters uses Scanner_ShiftRegs74HC165 to scan the secondary matrix.
|
Row_Ext_ShiftRegisters uses Scanner_ShiftRegs74HC165 to scan the peripheral matrix.
|
||||||
|
|
||||||
Class inheritance diagram
|
Class inheritance diagram
|
||||||
```
|
```
|
||||||
@ -68,7 +68,7 @@ Keybrd library class inheritance diagram
|
|||||||
```
|
```
|
||||||
________ Row ___________
|
________ Row ___________
|
||||||
/ | \
|
/ | \
|
||||||
Row_uC Row_ShiftRegisters Row_IOE (to be added)
|
Row_uC Row_ShiftRegisters Row_IOE (todo to be added)
|
||||||
|
|
||||||
|
|
||||||
Scanner_uC Scanner_Port Scanner_ShiftRegs74HC165
|
Scanner_uC Scanner_Port Scanner_ShiftRegs74HC165
|
||||||
@ -78,7 +78,7 @@ Keybrd library class inheritance diagram
|
|||||||
|
|
||||||
PortWrite
|
PortWrite
|
||||||
|
|
|
|
||||||
PortWrite_PCA9655E (one PortWrite class for each IOE type)
|
PortWrite_PCA9655E (one PortWrite class for each IOE type)
|
||||||
|
|
||||||
PortRead
|
PortRead
|
||||||
|
|
|
|
||||||
@ -115,9 +115,9 @@ Keybrd library class inheritance diagram
|
|||||||
| | |
|
| | |
|
||||||
| Code_LayeredScSc Code_LayeredCodeSc
|
| Code_LayeredScSc Code_LayeredCodeSc
|
||||||
|
|
|
|
||||||
|__________________________________________
|
|_________________________________________________________
|
||||||
\ \ \ \
|
\ \ \ \ \
|
||||||
Code_Sc Code_Shift Code_AutoShift Code_LEDLock
|
Code_Sc Code_Shift Code_AutoShift Code_LEDLock Code_Null
|
||||||
/ \
|
/ \
|
||||||
Code_ScS Code_ScNS
|
Code_ScS Code_ScNS
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ Dependency diagram of example multi-layer keyboard with layer LEDs
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Dependency diagram of example secondary matrix with shift registers
|
Dependency diagram of example peripheral matrix with shift registers
|
||||||
```
|
```
|
||||||
Row_ShiftRegisters[1..*]
|
Row_ShiftRegisters[1..*]
|
||||||
/ \ \
|
/ \ \
|
||||||
@ -159,17 +159,17 @@ Dependency diagram of example secondary matrix with shift registers
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Dependency diagram of example secondary matrix with I/O Expander and LEDs
|
Dependency diagram of example peripheral matrix with I/O Expander and LEDs
|
||||||
```
|
```
|
||||||
___ Row_IOE[1..*] _________
|
_____ Row_IOE[1..*] _________
|
||||||
/ \ \
|
/ \ \
|
||||||
_ Scanner_Port[1] _ Debouncer[1] Keys[1..*] __
|
__ Scanner_Port[1] __ Debouncer[1] Keys[1..*] __
|
||||||
/ | \ | \
|
/ | \ | \
|
||||||
PortWrite[1] RowPin[1] PortRead[1] Code[1..*] Code_LEDLock[1..*]
|
PortWrite[1] strobePin[1] PortRead[1] Code[1..*] Code_LEDLock[1..*]
|
||||||
\ / \ |
|
\ / \ |
|
||||||
\ / ColPins[1..*] LED[1]
|
\ / ColPins[1..*] LED[1]
|
||||||
\ /
|
\ /
|
||||||
PortIOE[0..*]
|
PortIOE[0..*]
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -243,7 +243,7 @@ Following the style guide makes it easier for the next programmer to understand
|
|||||||
Trace of keybrd scan
|
Trace of keybrd scan
|
||||||
--------------------
|
--------------------
|
||||||
Arduino does not have a debugger.
|
Arduino does not have a debugger.
|
||||||
So here is the next best thing; a list of functions in the order that they are called.
|
So here is a list of functions in the order that they are called.
|
||||||
The trace is of a one-row single-layer keybrd scan.
|
The trace is of a one-row single-layer keybrd scan.
|
||||||
Refer to it like a table of contents while reading the keybrd library.
|
Refer to it like a table of contents while reading the keybrd library.
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ Details are in config_key.h
|
|||||||
class PortRead
|
class PortRead
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
const uint8_t readPins; //bitwise pin configuration, 1 means read column
|
const uint8_t readPins; //bitwise pin configuration, 1 means read pin
|
||||||
public:
|
public:
|
||||||
PortRead(const uint8_t readPins): readPins(readPins) {}
|
PortRead(const uint8_t readPins): readPins(readPins) {}
|
||||||
virtual uint8_t read()=0;
|
virtual uint8_t read()=0;
|
||||||
|
23
src/PortRead_MCP23S17.cpp
Normal file
23
src/PortRead_MCP23S17.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include "PortRead_MCP23S17.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
PortRead_MCP23S17::begin() is not needed because port direction is already configured to input by default.
|
||||||
|
SPI bus is configured in PortWrite_MCP23S17::begin().
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
returns port value
|
||||||
|
*/
|
||||||
|
uint8_t PortRead_MCP23S17::read()
|
||||||
|
{
|
||||||
|
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
|
||||||
|
|
||||||
|
return portState;
|
||||||
|
}
|
42
src/PortRead_MCP23S17.h
Normal file
42
src/PortRead_MCP23S17.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef PORTREAD_MCP23S17_H
|
||||||
|
#define PORTREAD_MCP23S17_H
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <PortRead.h>
|
||||||
|
#include "PortIOE.h"
|
||||||
|
|
||||||
|
/* One MCP23S17 I/O expander port connected to matrix columns.
|
||||||
|
MCP23S17 does not have internal pull-up resistors (PCA9535E does).
|
||||||
|
|
||||||
|
Instantiation
|
||||||
|
------------
|
||||||
|
readPins 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)
|
||||||
|
|
||||||
|
Example instantiation for column port 0, with pins 2 and 3 connected to columns:
|
||||||
|
PortIOE port0(0, 0);
|
||||||
|
PortRead_MCP23S17 colPort0(port0, 2<<0 | 1<<3 );
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
class PortRead_MCP23S17 : public PortRead
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
PortIOE& port;
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
todo not all PortRead_ classes need a readPins
|
||||||
|
move PortRead::readPins from PortRead to PortRead_PCA9655E
|
||||||
|
remove PortRead(0) initialization from this constructor
|
||||||
|
*/
|
||||||
|
//The constructor initialization list is in .cpp
|
||||||
|
PortRead_MCP23S17(PortIOE& port) : PortRead(0), port(port) {}
|
||||||
|
virtual uint8_t read();
|
||||||
|
};
|
||||||
|
#endif
|
50
src/PortWrite_MCP23S17.cpp
Normal file
50
src/PortWrite_MCP23S17.cpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include "PortWrite_MCP23S17.h"
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
If PortRead_MCP23S17 is instantiated on the same port, do NOT use PortWrite_MCP23S17::begin().
|
||||||
|
Otherwise readPins could be overwritten.
|
||||||
|
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
|
||||||
|
SPI.begin();
|
||||||
|
SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //control SPI bus
|
||||||
|
|
||||||
|
writePort(port.num, 0); //configure port direction (port.num) to output (0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
pin is bitwise, where pin being strobed is 1.
|
||||||
|
strobe is HIGH or LOW (for active high or active low).
|
||||||
|
port.outputVal can be shared by 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)
|
||||||
|
{
|
||||||
|
if (strobe == LOW) //if active low
|
||||||
|
{
|
||||||
|
port.outputVal &= ~pin; //set pin output to low
|
||||||
|
}
|
||||||
|
else //if active high
|
||||||
|
{
|
||||||
|
port.outputVal |= pin; //set pin output to high
|
||||||
|
}
|
||||||
|
|
||||||
|
writePort(port.num + 0x12, port.outputVal); //set GPIO port pins for stobe and LEDs
|
||||||
|
}
|
46
src/PortWrite_MCP23S17.h
Normal file
46
src/PortWrite_MCP23S17.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef PORTWRITE_MCP23S17_H
|
||||||
|
#define PORTWRITE_MCP23S17_H
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <PortWrite.h>
|
||||||
|
#include "PortIOE.h"
|
||||||
|
|
||||||
|
/* One MCP23S17 I/O expander port connected to matrix rows.
|
||||||
|
MCP23S17 does not have internal pull-up resistors (PCA9535E does).
|
||||||
|
|
||||||
|
begin() configures column port's configuration and output.
|
||||||
|
This should normally be called once in sketch's setup().
|
||||||
|
If PortRead_MCP23S17 is instantiated on the same port, do NOT use PortWrite_MCP23S17::begin().
|
||||||
|
Otherwise readPins could be overwritten.
|
||||||
|
|
||||||
|
Instantiation
|
||||||
|
------------
|
||||||
|
Example instantiation for row port 0:
|
||||||
|
PortIOE port0(0, 0);
|
||||||
|
PortWrite_MCP23S17 rowPort0(port0);
|
||||||
|
|
||||||
|
Example instantiation for row port 1:
|
||||||
|
PortIOE port1(1, 0);
|
||||||
|
PortWrite_MCP23S17 rowPort1(port1);
|
||||||
|
|
||||||
|
Diode orientation
|
||||||
|
----------------
|
||||||
|
Diode orientation is explained in keybrd_library_user_guide.md > Diode orientation
|
||||||
|
|
||||||
|
MCP23S17 data sheet
|
||||||
|
----------------
|
||||||
|
http://www.onsemi.com/pub_link/Collateral/MCP23S17-D.PDF
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PortWrite_MCP23S17 : public PortWrite
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
PortIOE& port;
|
||||||
|
void writePort(const uint8_t registerAddr, const uint8_t data);
|
||||||
|
public:
|
||||||
|
PortWrite_MCP23S17(PortIOE& port) : port(port) {}
|
||||||
|
void begin();
|
||||||
|
virtual void write(const uint8_t pin, const bool level);
|
||||||
|
};
|
||||||
|
#endif
|
@ -14,8 +14,7 @@ class Row
|
|||||||
Key *const *const ptrsKeys; //array of Key pointers
|
Key *const *const ptrsKeys; //array of Key pointers
|
||||||
virtual void keyWasPressed();
|
virtual void keyWasPressed();
|
||||||
protected:
|
protected:
|
||||||
read_pins_t debounced; //bitwise state of keys after debouncing
|
read_pins_t debounced; //bitwise state of keys after debouncing, 1=pressed, 0=released
|
||||||
// 1 means pressed, 0 means released
|
|
||||||
void send(const uint8_t readPinCount, const read_pins_t debouncedChanged);
|
void send(const uint8_t readPinCount, const read_pins_t debouncedChanged);
|
||||||
public:
|
public:
|
||||||
Row(Key* const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { }
|
Row(Key* const ptrsKeys[]) : ptrsKeys(ptrsKeys), debounced(0) { }
|
||||||
|
12
src/Row_IOE.cpp
Normal file
12
src/Row_IOE.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "Row_IOE.h"
|
||||||
|
|
||||||
|
void Row_IOE::process()
|
||||||
|
{
|
||||||
|
//these variables are all bitwise, one bit per key
|
||||||
|
uint8_t readState; //1 means pressed, 0 means released
|
||||||
|
uint8_t debouncedChanged; //1 means debounced changed
|
||||||
|
|
||||||
|
readState = scanner.scan();
|
||||||
|
debouncedChanged = debouncer.debounce(readState, debounced);
|
||||||
|
send(readPinCount, debouncedChanged);
|
||||||
|
}
|
26
src/Row_IOE.h
Normal file
26
src/Row_IOE.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef ROW_IOE_H
|
||||||
|
#define ROW_IOE_H
|
||||||
|
|
||||||
|
#include <Row.h>
|
||||||
|
#include <Scanner_Port.h>
|
||||||
|
#include <Debouncer_Samples.h>
|
||||||
|
class PortWrite;
|
||||||
|
class PortRead;
|
||||||
|
|
||||||
|
/* Row_IOE is a row connected to an Input/Output Expander.
|
||||||
|
Configuration and Instantiation instructions are in keybrd/src/Row_IOE.h
|
||||||
|
*/
|
||||||
|
class Row_IOE : public Row
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Scanner_Port scanner;
|
||||||
|
Debouncer_Samples debouncer;
|
||||||
|
const uint8_t readPinCount; //number of read pins
|
||||||
|
public:
|
||||||
|
Row_IOE(PortWrite& refPortWrite, const uint8_t strobePin,
|
||||||
|
PortRead& refPortRead, const uint8_t readPinCount, Key *const ptrsKeys[])
|
||||||
|
: Row(ptrsKeys), scanner(refPortWrite, strobePin, refPortRead),
|
||||||
|
readPinCount(readPinCount) { }
|
||||||
|
void process();
|
||||||
|
};
|
||||||
|
#endif
|
@ -13,7 +13,7 @@ shift registers 74HC165 are Parallel-In-Serial-Out (PISO)
|
|||||||
Upto 4 shift registers can be in a daisy chained for a total of 32 read pins.
|
Upto 4 shift registers can be in a daisy chained for a total of 32 read pins.
|
||||||
|
|
||||||
For active low:
|
For active low:
|
||||||
Shift register parallel input pins have 10k pull-down resistors powered
|
Shift register parallel input pins have 10k pull-up resistors powered
|
||||||
Orient diodes with cathode (banded end) towards the write pins (row)
|
Orient diodes with cathode (banded end) towards the write pins (row)
|
||||||
Controller's MISO pin is connected to shift register's complementary serial output (/QH) pin
|
Controller's MISO pin is connected to shift register's complementary serial output (/QH) pin
|
||||||
Use these two lines in the sketch:
|
Use these two lines in the sketch:
|
||||||
|
Binary file not shown.
@ -32,7 +32,7 @@ Code_Sc s_c(KEY_C);
|
|||||||
Key* ptrsKeys_0[] = { &s_1, &s_a };
|
Key* ptrsKeys_0[] = { &s_1, &s_a };
|
||||||
Row_uC row_0(0, readPins, READ_PIN_COUNT, ptrsKeys_0);
|
Row_uC row_0(0, readPins, READ_PIN_COUNT, ptrsKeys_0);
|
||||||
|
|
||||||
Key* ptrsKeys_1[] = { &s_b, &s_c };
|
Key* ptrsKeys_1[] = { &s_b, &s_c };
|
||||||
Row_uC row_1(1, readPins, READ_PIN_COUNT, ptrsKeys_1);
|
Row_uC row_1(1, readPins, READ_PIN_COUNT, ptrsKeys_1);
|
||||||
|
|
||||||
// ################### MAIN ####################
|
// ################### MAIN ####################
|
||||||
|
@ -0,0 +1,96 @@
|
|||||||
|
/* tutorial_4a_split_keyboard_with_shift_registers.ino
|
||||||
|
Tested on Teensy LC and two 74HC165 shift registers.
|
||||||
|
|
||||||
|
The right matrix has 2 shift registers daisy chained.
|
||||||
|
|
||||||
|
Layout Layout
|
||||||
|
| Left |**0** | Right |**0**|**1**|**2**|**3**|**4**|**5**|**6**|**7**|
|
||||||
|
|:-----:|-----| |:-----:|-----|-----|-----|-----|-----|-----|-----|-----|
|
||||||
|
| **0** | x | | **0** | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||||||
|
| **1** | y | | **1** | a | b | c | d | e | f | g | h |
|
||||||
|
*/
|
||||||
|
// ################## GLOBAL ###################
|
||||||
|
// ================= INCLUDES ==================
|
||||||
|
#include <ScanDelay.h>
|
||||||
|
#include <Code_Sc.h>
|
||||||
|
|
||||||
|
//Left matrix
|
||||||
|
#include <Row_uC.h>
|
||||||
|
|
||||||
|
//Right matrix
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Row_ShiftRegisters.h>
|
||||||
|
|
||||||
|
// =============== CONFIGURATION ===============
|
||||||
|
ScanDelay scanDelay(9000);
|
||||||
|
|
||||||
|
// =================== CODES ===================
|
||||||
|
Code_Sc s_a(KEY_A);
|
||||||
|
Code_Sc s_b(KEY_B);
|
||||||
|
Code_Sc s_c(KEY_C);
|
||||||
|
Code_Sc s_d(KEY_D);
|
||||||
|
Code_Sc s_e(KEY_E);
|
||||||
|
Code_Sc s_f(KEY_F);
|
||||||
|
Code_Sc s_g(KEY_G);
|
||||||
|
|
||||||
|
Code_Sc s_x(KEY_X);
|
||||||
|
Code_Sc s_y(KEY_Y);
|
||||||
|
|
||||||
|
Code_Sc s_0(KEY_0);
|
||||||
|
Code_Sc s_1(KEY_1);
|
||||||
|
Code_Sc s_2(KEY_2);
|
||||||
|
Code_Sc s_3(KEY_3);
|
||||||
|
Code_Sc s_4(KEY_4);
|
||||||
|
Code_Sc s_5(KEY_5);
|
||||||
|
Code_Sc s_6(KEY_6);
|
||||||
|
|
||||||
|
// =============== LEFT MATRIX =================
|
||||||
|
//set left matrix for active low
|
||||||
|
const bool Scanner_uC::STROBE_ON = LOW;
|
||||||
|
const bool Scanner_uC::STROBE_OFF = HIGH;
|
||||||
|
|
||||||
|
//column pin
|
||||||
|
uint8_t readPins[] = {14};
|
||||||
|
uint8_t READ_PIN_COUNT = sizeof(readPins)/sizeof(*readPins);
|
||||||
|
|
||||||
|
//rows
|
||||||
|
Key* ptrsKeys_L0[] = { &s_x };
|
||||||
|
Row_uC row_L0(0, readPins, READ_PIN_COUNT, ptrsKeys_L0);
|
||||||
|
|
||||||
|
Key* ptrsKeys_L1[] = { &s_y };
|
||||||
|
Row_uC row_L1(1, readPins, READ_PIN_COUNT, ptrsKeys_L1);
|
||||||
|
|
||||||
|
// =============== RIGHT MATRIX ================
|
||||||
|
//set matrix to active high
|
||||||
|
const bool Scanner_ShiftRegs74HC165::STROBE_ON = HIGH;
|
||||||
|
const bool Scanner_ShiftRegs74HC165::STROBE_OFF = LOW;
|
||||||
|
|
||||||
|
//chip select pin
|
||||||
|
const uint8_t Scanner_ShiftRegs74HC165::SHIFT_LOAD = 10;
|
||||||
|
|
||||||
|
//rows
|
||||||
|
Key* ptrsKeys_R0[] = { &s_6, &s_5, &s_4, &s_3, //shift regiser on right
|
||||||
|
&s_c, &s_d, &s_e, &s_f,
|
||||||
|
&s_2, &s_1, &s_0, &s_g, //shift regiser on left
|
||||||
|
&s_a, &s_b }; //unused input pins are grounded
|
||||||
|
Row_ShiftRegisters row_R0(0, sizeof(ptrsKeys_R0)/sizeof(*ptrsKeys_R0), ptrsKeys_R0);
|
||||||
|
|
||||||
|
// ################### MAIN ####################
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Keyboard.begin();
|
||||||
|
SPI.begin();
|
||||||
|
row_R0.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
//left matrix
|
||||||
|
row_L0.process();
|
||||||
|
row_L1.process();
|
||||||
|
|
||||||
|
//right matrix
|
||||||
|
row_R0.process();
|
||||||
|
|
||||||
|
scanDelay.delay();
|
||||||
|
}
|
105
tutorials/keybrd_4c_split_with_IOE/keybrd_4c_split_with_IOE.ino
Normal file
105
tutorials/keybrd_4c_split_with_IOE/keybrd_4c_split_with_IOE.ino
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/* keybrd_4c_split_with_IOE_annotated.ino
|
||||||
|
|
||||||
|
| Left | **0** | **1** | | Right | **0** | **1** |
|
||||||
|
|:-----:|-------|-------| |:-----:|-------|-------|
|
||||||
|
| **0** | a | b | | **0** | 1 | 2 |
|
||||||
|
| **1** | shift | c | | **1** | 3 | shift |
|
||||||
|
|
||||||
|
| Left | **0** | **1** | | Right | **0** | **1** | todo
|
||||||
|
|:-----:|-------|-------| |:-----:|-------|-------|
|
||||||
|
| **1** | 1 | 2 | | **1** | 3 | 4 |
|
||||||
|
| **0** | a | b | | **0** | c | d |
|
||||||
|
*/
|
||||||
|
// ################## GLOBAL ###################
|
||||||
|
// ================= INCLUDES ==================
|
||||||
|
#include <ScanDelay.h>
|
||||||
|
#include <Code_Sc.h>
|
||||||
|
|
||||||
|
//left matrix
|
||||||
|
#include <Row_uC.h>
|
||||||
|
|
||||||
|
//right matrix
|
||||||
|
#include <Row_IOE.h>
|
||||||
|
#include <PortIOE.h>
|
||||||
|
#include <PortWrite_MCP23S17.h>
|
||||||
|
#include <PortRead_MCP23S17.h>
|
||||||
|
|
||||||
|
// ============ SPEED CONFIGURATION ============
|
||||||
|
ScanDelay scanDelay(9000);
|
||||||
|
|
||||||
|
// ================ LEFT MATRIX ================
|
||||||
|
// ---------------- ACTIVE STATE ---------------
|
||||||
|
const bool Scanner_uC::STROBE_ON = LOW; //active low
|
||||||
|
const bool Scanner_uC::STROBE_OFF = HIGH;
|
||||||
|
|
||||||
|
// ------------------- PINS --------------------
|
||||||
|
uint8_t readPins[] = {14, 15};
|
||||||
|
|
||||||
|
// ================ RIGHT MATRIX ===============
|
||||||
|
const bool Scanner_Port::STROBE_ON = HIGH; //active high
|
||||||
|
const bool Scanner_Port::STROBE_OFF = LOW;
|
||||||
|
|
||||||
|
const uint8_t PortIOE::ADDR = 0x18;
|
||||||
|
|
||||||
|
// ------------------ PORT 1 -------------------
|
||||||
|
PortIOE port1_R(1, 0);
|
||||||
|
PortWrite_MCP23S17 portWrite1_R(port1_R);
|
||||||
|
|
||||||
|
// ------------------ PORT 0 -------------------
|
||||||
|
PortIOE port0_R(0, 0);
|
||||||
|
PortWrite_MCP23S17 portWrite0_R(port0_R);
|
||||||
|
PortRead_MCP23S17 portRead0_R(port0_R, 1<<0 | 1<<1 );
|
||||||
|
|
||||||
|
// =================== CODES ===================
|
||||||
|
Code_Sc s_shiftL(MODIFIERKEY_LEFT_SHIFT);
|
||||||
|
Code_Sc s_shiftR(MODIFIERKEY_RIGHT_SHIFT);
|
||||||
|
|
||||||
|
Code_Sc s_a(KEY_A);
|
||||||
|
Code_Sc s_b(KEY_B);
|
||||||
|
Code_Sc s_c(KEY_C);
|
||||||
|
Code_Sc s_1(KEY_1);
|
||||||
|
Code_Sc s_2(KEY_2);
|
||||||
|
Code_Sc s_3(KEY_3);
|
||||||
|
|
||||||
|
// =================== ROWS ====================
|
||||||
|
// ---------------- LEFT ROWS ------------------
|
||||||
|
Key* ptrsKeys_L0[] = { &s_a, &s_b };
|
||||||
|
const uint8_t KEY_COUNT_L0 = sizeof(ptrsKeys_L0)/sizeof(*ptrsKeys_L0);
|
||||||
|
Row_uC row_L0(0, readPins, KEY_COUNT_L0, ptrsKeys_L0);
|
||||||
|
|
||||||
|
Key* ptrsKeys_L1[] = { &s_c, &s_shiftL };
|
||||||
|
const uint8_t KEY_COUNT_L1 = sizeof(ptrsKeys_L1)/sizeof(*ptrsKeys_L1);
|
||||||
|
Row_uC row_L1(1, readPins, KEY_COUNT_L1, ptrsKeys_L1);
|
||||||
|
|
||||||
|
// ---------------- RIGHT ROWS -----------------
|
||||||
|
Key* ptrsKeys_R0[] = { &s_1, &s_2 };
|
||||||
|
const 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);
|
||||||
|
|
||||||
|
Key* ptrsKeys_R1[] = { &s_3, &s_shiftR };
|
||||||
|
const 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);
|
||||||
|
|
||||||
|
// ################### MAIN ####################
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Keyboard.begin();
|
||||||
|
Wire.begin(); //Wire.begin() must be called before port begin()
|
||||||
|
portWrite1_R.begin();
|
||||||
|
portRead0_R.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
//left matrix
|
||||||
|
row_L0.process();
|
||||||
|
row_L1.process();
|
||||||
|
|
||||||
|
//right matrix
|
||||||
|
row_R0.process();
|
||||||
|
row_R1.process();
|
||||||
|
|
||||||
|
scanDelay.delay();
|
||||||
|
//debug.print_scans_per_second();
|
||||||
|
//debug.print_microseconds_per_scan();
|
||||||
|
}
|
@ -1,19 +1,38 @@
|
|||||||
Tutorial 10 - writing IOE Port classes
|
Tutorial 10 - writing new IOE Port classes
|
||||||
===========================================
|
==========================================
|
||||||
Port classes are the keybrd library's interface to I/O expander ports.
|
Port classes are the keybrd library's interface to I/O expander ports.
|
||||||
|
|
||||||
To write your own Port class:
|
To write a new Port class:
|
||||||
|
|
||||||
1. Get a copy of the I/O expander datasheet.
|
1. Get a copy of the I/O expander's datasheet.
|
||||||
2. Study other keybrd Port classes.
|
2. An I/O expander will use one of two communication protocols: [http://www.byteparadigm.com/applications/introduction-to-i2c-and-spi-protocols/](SPI or I2C).
|
||||||
|
Refer to the [Arduino SPI](https://www.arduino.cc/en/Reference/SPI)
|
||||||
For example, the keybrd_DH library uses these keybrd classes for its PCA9655E I/O expander:
|
or [Arduino Wire (I2C)](https://www.arduino.cc/en/Reference/Wire) library
|
||||||
* PortWrite_PCA9655E
|
3. Get familiar with your I/O expander.
|
||||||
* PortRead_PCA9655E
|
Different I/O expanders use different commands (a.k.a. operation codes).
|
||||||
* LED_PCA9655E
|
Refer to your I/O expander's datasheet for read and write commands.
|
||||||
|
Search for Arduino sketch examples containing your I/O expander
|
||||||
Debugging I/O expander code is hard because SPI or I2C protocol adds a level of indirection.
|
([sumotoy](https://github.com/sumotoy/gpio_expander) has a large gpio expander library).
|
||||||
If you haven't written Arduino code for an I/O expander before, learn from an Arduiono I/O expander tutorial before attempting it here.
|
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_write/
|
||||||
|
Simple I2C I/O expander examples:
|
||||||
|
todo link, pictures
|
||||||
|
read
|
||||||
|
write
|
||||||
|
4. Study other keybrd Port classes.
|
||||||
|
Port classes for SPI MCP23S17 I/O expander:
|
||||||
|
*todo
|
||||||
|
*
|
||||||
|
*
|
||||||
|
Port classes for I2C PCA9655E I/O expander:
|
||||||
|
* PortWrite_PCA9655E todo link
|
||||||
|
* PortRead_PCA9655E
|
||||||
|
* LED_PCA9655E
|
||||||
|
5. Write similar Port classes for your I/O expander.
|
||||||
|
Debugging I/O expander code is hard because SPI or I2C protocol adds a level of indirection.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<a rel="license" href="https://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://licensebuttons.net/l/by/4.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">keybrd tutorial</span> by <a xmlns:cc="https://creativecommons.org/ns" href="https://github.com/wolfv6/keybrd" property="cc:attributionName" rel="cc:attributionURL">Wolfram Volpi</a> is licensed under a <a rel="license" href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.<br />Permissions beyond the scope of this license may be available at <a xmlns:cc="https://creativecommons.org/ns" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
<a rel="license" href="https://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://licensebuttons.net/l/by/4.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">keybrd tutorial</span> by <a xmlns:cc="https://creativecommons.org/ns" href="https://github.com/wolfv6/keybrd" property="cc:attributionName" rel="cc:attributionURL">Wolfram Volpi</a> is licensed under a <a rel="license" href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.<br />Permissions beyond the scope of this license may be available at <a xmlns:cc="https://creativecommons.org/ns" href="https://github.com/wolfv6/keybrd/issues/new" rel="cc:morePermissions">https://github.com/wolfv6/keybrd/issues/new</a>.
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
Tutorial 8b - creating and publishing your own keybrd extension library
|
Tutorial 8b - sharing your keybrd extension library
|
||||||
=======================================================================
|
===================================================
|
||||||
Publishing and listing your keybrd extension library allows others to find and install your library.
|
Publishing and listing your keybrd extension library allows others to find and install your library.
|
||||||
The keybrd extension library name should start with "keybrd_" so that it is easy for other people to find.
|
The keybrd extension library name should start with "keybrd_" so that it is easy for other people to find.
|
||||||
|
|
||||||
There are two ways to publish and list an Arduino library.
|
There are two ways to publish and list an Arduino library.
|
||||||
|
|
||||||
Publishing anywhere with listing on Arduino Playground LibraryList
|
Publish anywhere and list on Arduino Playground
|
||||||
------------------------------------------------------------------
|
-----------------------------------------------
|
||||||
Publishing your keybrd extension library with the following directory structure makes it easy for others to understand.
|
Publishing your keybrd extension library with the following directory structure makes it easy for others to understand.
|
||||||
|
|
||||||
keybrd_MyKeyboard/
|
keybrd_MyKeyboard/
|
||||||
@ -25,16 +25,13 @@ Publishing your keybrd extension library with the following directory structure
|
|||||||
instantiations_codes.h
|
instantiations_codes.h
|
||||||
instantiations_rows.h
|
instantiations_rows.h
|
||||||
|
|
||||||
When your ready to list your keybrd extension library, go to the [Arduino Playground keybrd page](http://playground.arduino.cc/Main/keybrd).
|
When your ready to list your keybrd extension library,
|
||||||
|
add a link and short description of your keybrd extension library to the [Arduino Playground keybrd page](http://playground.arduino.cc/Main/keybrd) under "keybrd extension libraries".
|
||||||
Arduino playground is a wiki.
|
Arduino playground is a wiki.
|
||||||
Links on how to edit the wiki are on the bottom left under "Participate".
|
Links on how to edit the wiki are on the bottom left under "Participate".
|
||||||
|
|
||||||
You can also add a picture of a keyboard that uses your keybrd extension library.
|
Publish on GitHub and list on Arduino Library-Manager and Arduino Playground
|
||||||
Uploading files to the Playground is not allowed for standard users.
|
----------------------------------------------------------------------------
|
||||||
So if you want to add a picture, it will need to be hosted somewhere else.
|
|
||||||
|
|
||||||
Publishing on GitHub with listing on Arduino Library-Manager and Arduino Playground LibraryList
|
|
||||||
-----------------------------------------------------------------------------------------------
|
|
||||||
The advantage of using GitHub is that users can submit pull requests.
|
The advantage of using GitHub is that users can submit pull requests.
|
||||||
The advantage of using Arduino Library-Manager is that users can easily find and install your library through the Arduino IDE.
|
The advantage of using Arduino Library-Manager is that users can easily find and install your library through the Arduino IDE.
|
||||||
|
|
||||||
@ -78,14 +75,11 @@ Example library.properties file:
|
|||||||
Instructions for listing a library on Arduino Library Manager are at:
|
Instructions for listing a library on Arduino Library Manager are at:
|
||||||
https://github.com/arduino/Arduino/wiki/Library-Manager-FAQ
|
https://github.com/arduino/Arduino/wiki/Library-Manager-FAQ
|
||||||
|
|
||||||
After it has been accepted into the Arduino IDE Library Manager, add your keybrd extension library to the [Arduino Playground keybrd page](http://playground.arduino.cc/Main/keybrd).
|
After it has been accepted into the Arduino IDE Library Manager,
|
||||||
|
add a link and short description of your keybrd extension library to the [Arduino Playground keybrd page](http://playground.arduino.cc/Main/keybrd) under "keybrd extension libraries".
|
||||||
Arduino playground is a wiki.
|
Arduino playground is a wiki.
|
||||||
Links on how to edit the wiki are on the bottom left under "Participate".
|
Links on how to edit the wiki are on the bottom left under "Participate".
|
||||||
|
|
||||||
You can also add a picture of a keyboard that uses your keybrd extension library.
|
|
||||||
Uploading files to the Playground is not allowed for standard users.
|
|
||||||
So if you want to add a picture, it will need to be hosted somewhere else.
|
|
||||||
|
|
||||||
To publish a new release of a library that is already listed on Arduino Library Manager
|
To publish a new release of a library that is already listed on Arduino Library Manager
|
||||||
|
|
||||||
1. Update the version in your library.properties file:
|
1. Update the version in your library.properties file:
|
17
tutorials/tutorial_8c_sharing_your_keybrd_sketch.md
Normal file
17
tutorials/tutorial_8c_sharing_your_keybrd_sketch.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
Tutorial 8c - sharing your keybrd sketch
|
||||||
|
========================================
|
||||||
|
keybrd sketches that use a keybrd extension library should be published in the extension library's examples directory.
|
||||||
|
keybrd sketches that do not use a keybrd extension library can be published anywhere.
|
||||||
|
|
||||||
|
Publishing and listing your keybrd sketch allows others to find your sketch.
|
||||||
|
|
||||||
|
Publish anywhere and list on Arduino Playground
|
||||||
|
-----------------------------------------------
|
||||||
|
Publish your sketch anywhere. Some free places are:
|
||||||
|
* GitHub repository
|
||||||
|
* [GitHub Gist](https://help.github.com/categories/gists/)
|
||||||
|
* [geekhack Making Stuff Together!](https://geekhack.org/index.php?board=117.0)
|
||||||
|
|
||||||
|
Then add a link and short description of your keybrd sketch to the [Arduino Playground keybrd page](http://playground.arduino.cc/Main/keybrd) under "keybrd sketches".
|
||||||
|
Arduino playground is a wiki.
|
||||||
|
Links on how to edit the wiki are on the bottom left under "Participate".
|
42
unit_tests/MCP23S17_read/MCP23S17_read.ino
Normal file
42
unit_tests/MCP23S17_read/MCP23S17_read.ino
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* this works
|
||||||
|
The setup is an MCP23S17 I/O expander on a Teensy LC controller.
|
||||||
|
MCP23S17 port B pins are alternately grounded and energized.
|
||||||
|
portBState is a bitwise reading of port B.
|
||||||
|
output is: 10101010
|
||||||
|
|
||||||
|
posted on http://arduino.stackexchange.com/questions/tagged/spi
|
||||||
|
http://arduino.stackexchange.com/questions/28792/reading-an-mcp23s17-i-o-expander-port-with-the-arduino-spi-library
|
||||||
|
*/
|
||||||
|
#include <SPI.h>
|
||||||
|
|
||||||
|
const uint8_t ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded
|
||||||
|
const uint8_t OPCODE_READ = (ADDR << 1 | 0x01); //MCP23S17 opcode read has LSB set
|
||||||
|
|
||||||
|
const uint8_t IODIRB = 0x01;
|
||||||
|
const uint8_t GPIOB = 0x13;
|
||||||
|
|
||||||
|
uint8_t portBState = 0; //bit wise
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(9600);
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
pinMode(SS, OUTPUT); //configure controller's Slave Select pin to output
|
||||||
|
digitalWrite(SS, HIGH); //disable Slave Select
|
||||||
|
SPI.begin();
|
||||||
|
|
||||||
|
//IODIRB register is already configured to input by default
|
||||||
|
|
||||||
|
SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //gain control of SPI bus
|
||||||
|
digitalWrite(SS, LOW); //enable Slave Select
|
||||||
|
SPI.transfer(OPCODE_READ); //read command
|
||||||
|
SPI.transfer(GPIOB); //register address to read data from
|
||||||
|
portBState = SPI.transfer(0); //save the data (0 is dummy data to send)
|
||||||
|
digitalWrite(SS, HIGH); //disable Slave Select
|
||||||
|
SPI.endTransaction(); //release the SPI bus
|
||||||
|
|
||||||
|
Serial.println(portBState, BIN); //should print 10101010
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() { }
|
54
unit_tests/MCP23S17_write/MCP23S17_write.ino
Normal file
54
unit_tests/MCP23S17_write/MCP23S17_write.ino
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/* this works with volt meter (MCP23S17 on 3.3v does not output enough power for LEDs)
|
||||||
|
LED lights w/o resistor, not light with 56 ohm resistor
|
||||||
|
blink LED on MCP23S17 port A pin
|
||||||
|
from Example 41.1 - Microchip MCP23017 with Arduino
|
||||||
|
http://tronixstuff.com/tutorials > chapter 41
|
||||||
|
http://tronixstuff.com/2011/08/26/tutorial-maximising-your-arduinos-io-ports/
|
||||||
|
John Boxall | CC by-sa-nc
|
||||||
|
from http://69.5.26.215/forum/?id=10945&page=3 #35
|
||||||
|
modified to test MCP23S17 (SPI) using syntax from
|
||||||
|
http://arduino.stackexchange.com/questions/16348/how-do-you-use-spi-on-an-arduino
|
||||||
|
>
|
||||||
|
|
||||||
|
SPISettings from http://arduino.stackexchange.com/questions/14191/mcp23s17-programming-iodirx-register-works-in-loop-but-not-in-setup
|
||||||
|
*/
|
||||||
|
#include <SPI.h>
|
||||||
|
|
||||||
|
const uint8_t ADDR = 0x20; //MCP23S17 address, all ADDR pins are grounded
|
||||||
|
const uint8_t OPCODE_WRITE = (ADDR << 1); //MCP23S17 opcode write has LSB clear
|
||||||
|
|
||||||
|
const uint8_t IODIRA = 0x00; //LEDs are on port A
|
||||||
|
const uint8_t GPIOA = 0x12;
|
||||||
|
|
||||||
|
uint8_t LED_state = 0; //bit wise
|
||||||
|
|
||||||
|
void IOEWrite(const uint8_t registerAddr, const uint8_t data)
|
||||||
|
{
|
||||||
|
SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //slower clock
|
||||||
|
digitalWrite(SS, LOW); //enable Slave Select
|
||||||
|
SPI.transfer(OPCODE_WRITE); //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
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
pinMode(SS, OUTPUT); //configure controller's Slave Select pin to output
|
||||||
|
digitalWrite(SS, HIGH); //disable Slave Select
|
||||||
|
SPI.begin();
|
||||||
|
|
||||||
|
IOEWrite(IODIRA, 0x00); //configure IODIRA register to output
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
IOEWrite(GPIOA, LED_state); //set all GPIOA pins
|
||||||
|
|
||||||
|
delay(2000);
|
||||||
|
//Serial.println(LED_state, BIN); //prints alternating 0 and 11111111
|
||||||
|
LED_state = ~LED_state; //toggle LED on/off
|
||||||
|
}
|
32
unit_tests/PortRead_MCP23S17/PortRead_MCP23S17.ino
Normal file
32
unit_tests/PortRead_MCP23S17/PortRead_MCP23S17.ino
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* unit test for PortRead_MCP23S17
|
||||||
|
The setup is an MCP23S17 I/O expander on a Teensy LC controller.
|
||||||
|
MCP23S17 port-B pins are alternately grounded and energized.
|
||||||
|
portBState is a bitwise reading of port B.
|
||||||
|
output is: 10101010
|
||||||
|
|
||||||
|
posted on http://arduino.stackexchange.com/questions/tagged/spi
|
||||||
|
http://arduino.stackexchange.com/questions/28792/reading-an-mcp23s17-i-o-expander-port-with-the-arduino-spi-library
|
||||||
|
*/
|
||||||
|
#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()
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
uint8_t portBState; //bit wise
|
||||||
|
|
||||||
|
delay(6000);
|
||||||
|
portBWrite.begin();
|
||||||
|
|
||||||
|
portBState = portBRead.read();
|
||||||
|
Keyboard.print("portBState = ");
|
||||||
|
Keyboard.println(portBState, BIN); //should print 10101010
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() { }
|
35
unit_tests/PortWrite_MCP23S17/PortWrite_MCP23S17.ino
Normal file
35
unit_tests/PortWrite_MCP23S17/PortWrite_MCP23S17.ino
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* unit test for PortRead_MCP23S17
|
||||||
|
The setup is an MCP23S17 I/O expander on a Teensy LC controller.
|
||||||
|
MCP23S17 port-A GPIO pins are not connected to anything.
|
||||||
|
Port-A GPIO-pin ouputs alternate between 0 and 3.3 volts.
|
||||||
|
|
||||||
|
Use a volt meter to measure port-A GPIO-pin ouputs.
|
||||||
|
MCP23S17 on 3.3v does not output enough power to reliable light LEDs
|
||||||
|
LED lights w/o resistor
|
||||||
|
LED not light with 56 ohm resistor
|
||||||
|
*/
|
||||||
|
#include "PortIOE.h"
|
||||||
|
#include "PortWrite_MCP23S17.h"
|
||||||
|
|
||||||
|
const uint8_t PortIOE::ADDR = 0x20; //MCP23S17 address, all 3 ADDR pins are grounded
|
||||||
|
PortIOE portA(0, 0);
|
||||||
|
|
||||||
|
PortWrite_MCP23S17 portAWrite(portA); //PortAWrite needed for begin()
|
||||||
|
|
||||||
|
const uint8_t GPIOA = 0x12; //LEDs are on port A
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
delay(6000);
|
||||||
|
portAWrite.begin();
|
||||||
|
//Keyboard.print("start blinking");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
portAWrite.write(~0, HIGH); //set all GPIOA pins HIGH
|
||||||
|
delay(2000);
|
||||||
|
|
||||||
|
portAWrite.write(~0, LOW); //set all GPIOA pins LOW
|
||||||
|
delay(2000);
|
||||||
|
}
|
Reference in New Issue
Block a user