mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.1.1 MCP23S17
This commit is contained in:
parent
06446a5024
commit
b0d88122db
@ -1,14 +1,15 @@
|
||||
//
|
||||
// FILE: MCP23S17.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.0
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: Arduino library for SPI MCP23S17 16 channel port expander
|
||||
// DATE: 2021-12-30
|
||||
// URL: https://github.com/RobTillaart/MCP23S17_RT
|
||||
// URL: https://github.com/RobTillaart/MCP23S17
|
||||
|
||||
//
|
||||
// HISTORY:
|
||||
// 0.1.0 2021-12-30 initial version (a 2019 version did not make it)
|
||||
// 0.1.1 2022-01-10 add 16 bit interface
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
@ -476,6 +477,94 @@ bool MCP23S17::getPullup8(uint8_t port, uint8_t &mask)
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// 16 pins interface
|
||||
// two register at once
|
||||
// value = 0..0xFFFF bit pattern
|
||||
bool MCP23S17::pinMode16(uint16_t value)
|
||||
{
|
||||
writeReg(MCP23S17_DDR_A, value >> 8);
|
||||
writeReg(MCP23S17_DDR_B, value & 8);
|
||||
_error = MCP23S17_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// value = 0..0xFFFF bit pattern
|
||||
bool MCP23S17::write16(uint16_t value)
|
||||
{
|
||||
writeReg(MCP23S17_GPIO_A, value >> 8);
|
||||
writeReg(MCP23S17_GPIO_B, value & 8);
|
||||
_error = MCP23S17_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// return = 0..0xFFFF bit pattern
|
||||
uint16_t MCP23S17::read16()
|
||||
{
|
||||
_error = MCP23S17_OK;
|
||||
uint16_t value = readReg(MCP23S17_GPIO_A);
|
||||
value <<= 8;
|
||||
value += readReg(MCP23S17_GPIO_B);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// mask = 0..0xFFFF bit pattern
|
||||
bool MCP23S17::setPolarity16(uint16_t mask)
|
||||
{
|
||||
writeReg(MCP23S17_POL_A, mask >> 8);
|
||||
writeReg(MCP23S17_POL_B, mask & 8);
|
||||
if (_error != MCP23S17_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// mask = 0..0xFFFF bit pattern
|
||||
bool MCP23S17::getPolarity16(uint16_t &mask)
|
||||
{
|
||||
mask = readReg(MCP23S17_POL_A);
|
||||
mask <<= 8;
|
||||
mask += readReg(MCP23S17_POL_B);
|
||||
if (_error != MCP23S17_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// mask = 0..0xFFFF bit pattern
|
||||
bool MCP23S17::setPullup16(uint16_t mask)
|
||||
{
|
||||
writeReg(MCP23S17_PUR_A, mask >> 8);
|
||||
writeReg(MCP23S17_PUR_B, mask & 8);
|
||||
if (_error != MCP23S17_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// mask = 0..0xFFFF bit pattern
|
||||
bool MCP23S17::getPullup16(uint16_t &mask)
|
||||
{
|
||||
mask = readReg(MCP23S17_PUR_A);
|
||||
mask <<= 8;
|
||||
mask += readReg(MCP23S17_PUR_B);
|
||||
if (_error != MCP23S17_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int MCP23S17::lastError()
|
||||
{
|
||||
int e = _error;
|
||||
@ -487,13 +576,13 @@ int MCP23S17::lastError()
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
// PRIVATE
|
||||
//
|
||||
//
|
||||
|
||||
bool MCP23S17::writeReg(uint8_t reg, uint8_t value)
|
||||
{
|
||||
_error = MCP23S17_OK;
|
||||
|
||||
if (reg > MCP23S17_OLAT_B)
|
||||
if (reg > MCP23S17_OLAT_B)
|
||||
{
|
||||
_error = 0xFF; // TODO MAGIC NR
|
||||
return false;
|
||||
@ -524,7 +613,7 @@ uint8_t MCP23S17::readReg(uint8_t reg)
|
||||
|
||||
_error = MCP23S17_OK;
|
||||
|
||||
if (reg > MCP23S17_OLAT_B)
|
||||
if (reg > MCP23S17_OLAT_B)
|
||||
{
|
||||
_error = 0xFF; // TODO MAGIC NR
|
||||
return false;
|
||||
|
@ -5,28 +5,7 @@
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: Arduino library for SPI MCP23S17 16 channel port expander
|
||||
// DATE: 2021-12-30
|
||||
// URL: https://github.com/RobTillaart/MCP23S17_RT
|
||||
//
|
||||
// dip layout
|
||||
//
|
||||
// +-----||-----+
|
||||
// GPB0 | o o | GPA7
|
||||
// GPB1 | o o | GPA6
|
||||
// GPB2 | o o | GPA5
|
||||
// GPB3 | o o | GPA4
|
||||
// GPB4 | o o | GPA3
|
||||
// GPB5 | o o | GPA2
|
||||
// GPB6 | o o | GPA1
|
||||
// GPB7 | o o | GPA0
|
||||
// +5V | o o | INTA
|
||||
// GND | o o | INTB
|
||||
// _CS_ | o o | _RESET_
|
||||
// CLK | o o | A2
|
||||
// SI | o o | A1
|
||||
// SO | o o | A0
|
||||
// +------------+
|
||||
//
|
||||
// note: Connect Address pins (default GND == address 0x00)
|
||||
// URL: https://github.com/RobTillaart/MCP23S17
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
@ -48,39 +27,49 @@
|
||||
class MCP23S17
|
||||
{
|
||||
public:
|
||||
// MCP23S17();
|
||||
|
||||
MCP23S17(uint8_t select, uint8_t dataIn, uint8_t dataOut, uint8_t clock, uint8_t address = 0x00);
|
||||
MCP23S17(uint8_t select, uint8_t address = 0x00);
|
||||
|
||||
bool begin();
|
||||
bool isConnected(); // needed ?
|
||||
bool begin();
|
||||
bool isConnected(); // needed ?
|
||||
|
||||
|
||||
// single pin interface
|
||||
// mode = INPUT, OUTPUT or INPUT_PULLUP (==INPUT)
|
||||
bool pinMode(uint8_t pin, uint8_t mode);
|
||||
bool digitalWrite(uint8_t pin, uint8_t value);
|
||||
uint8_t digitalRead(uint8_t pin);
|
||||
bool pinMode(uint8_t pin, uint8_t mode);
|
||||
bool digitalWrite(uint8_t pin, uint8_t value);
|
||||
uint8_t digitalRead(uint8_t pin);
|
||||
|
||||
bool setPolarity(uint8_t pin, bool reversed);
|
||||
bool getPolarity(uint8_t pin, bool &reversed);
|
||||
bool setPullup(uint8_t pin, bool pullup);
|
||||
bool getPullup(uint8_t pin, bool &pullup);
|
||||
bool setPolarity(uint8_t pin, bool reversed);
|
||||
bool getPolarity(uint8_t pin, bool &reversed);
|
||||
bool setPullup(uint8_t pin, bool pullup);
|
||||
bool getPullup(uint8_t pin, bool &pullup);
|
||||
|
||||
|
||||
// 8 pins interface
|
||||
// port = 0..1
|
||||
// value = bit pattern
|
||||
bool pinMode8(uint8_t port, uint8_t value);
|
||||
bool write8(uint8_t port, uint8_t value);
|
||||
int read8(uint8_t port);
|
||||
bool pinMode8(uint8_t port, uint8_t value);
|
||||
bool write8(uint8_t port, uint8_t value);
|
||||
int read8(uint8_t port);
|
||||
|
||||
bool setPolarity8(uint8_t port, uint8_t mask);
|
||||
bool getPolarity8(uint8_t port, uint8_t &mask);
|
||||
bool setPullup8(uint8_t port, uint8_t mask);
|
||||
bool getPullup8(uint8_t port, uint8_t &mask);
|
||||
|
||||
|
||||
bool setPolarity8(uint8_t port, uint8_t mask);
|
||||
bool getPolarity8(uint8_t port, uint8_t &mask);
|
||||
bool setPullup8(uint8_t port, uint8_t mask);
|
||||
bool getPullup8(uint8_t port, uint8_t &mask);
|
||||
// 16 pins interface
|
||||
// value = bit pattern
|
||||
bool pinMode16(uint16_t value);
|
||||
bool write16(uint16_t value);
|
||||
uint16_t read16();
|
||||
|
||||
bool setPolarity16(uint16_t mask);
|
||||
bool getPolarity16(uint16_t &mask);
|
||||
bool setPullup16(uint16_t mask);
|
||||
bool getPullup16(uint16_t &mask);
|
||||
|
||||
|
||||
// speed in Hz
|
||||
void setSPIspeed(uint32_t speed);
|
||||
@ -91,15 +80,15 @@ public:
|
||||
int lastError();
|
||||
|
||||
private:
|
||||
bool writeReg(uint8_t reg, uint8_t value);
|
||||
uint8_t readReg(uint8_t reg);
|
||||
bool writeReg(uint8_t reg, uint8_t value);
|
||||
uint8_t readReg(uint8_t reg);
|
||||
|
||||
uint8_t _address = 0;
|
||||
uint8_t _select = 0;
|
||||
uint8_t _dataOut = 0;
|
||||
uint8_t _dataIn = 0;
|
||||
uint8_t _clock = 0;
|
||||
uint8_t _error = MCP23S17_OK;
|
||||
uint8_t _address = 0;
|
||||
uint8_t _select = 0;
|
||||
uint8_t _dataOut = 0;
|
||||
uint8_t _dataIn = 0;
|
||||
uint8_t _clock = 0;
|
||||
uint8_t _error = MCP23S17_OK;
|
||||
|
||||
bool _hwSPI = false;
|
||||
uint32_t _SPIspeed = 8000000UL; // 1MHz is a safe value TODO CHECK datasheet
|
||||
|
@ -15,7 +15,7 @@ Arduino library for MCP23S17 16 channel SPI port expander.
|
||||
|
||||
This experimental library gives easy control over the 16 pins of a (SPI) MCP23S17 chip.
|
||||
|
||||
This IC is strongly related tot the MCP23017 I2C port expander - https://github.com/RobTillaart/MCP23017_RT
|
||||
This IC is strongly related to the MCP23017 I2C port expander - https://github.com/RobTillaart/MCP23017_RT
|
||||
Programming Interface is kept the same as much as possible.
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ Programming Interface is kept the same as much as possible.
|
||||
- **MCP23S17(uint8_t select, uint8_t data, uint8_t clock)** constructor SW SPI
|
||||
- **MCP23S17(uint8_t select)** constructor HW SPI
|
||||
- **bool begin()** returns true if successful.
|
||||
- **bool isConnected()** returns true if connected, false otherwise.
|
||||
- **bool isConnected()** returns true if connected, false otherwise. (dummy)
|
||||
|
||||
|
||||
### Single pin interface
|
||||
@ -47,10 +47,21 @@ Programming Interface is kept the same as much as possible.
|
||||
- **uint8_t read8(uint8_t port)** port = 0..1, reads 8 pins into one byte.
|
||||
- **bool setPolarity8(uint8_t port, uint8_t mask)** port = 0..1, sets polarity for 8 channels at once.
|
||||
- **bool getPolarity8(uint8_t port, uint8_t &mask)** port = 0..1, reads polarity of 8 channels at once.
|
||||
- **bool setPullup8(uint8_t port, uint8_t mask)** port = 0..1,, sets pull-up for 8 channels at once.
|
||||
- **bool setPullup8(uint8_t port, uint8_t mask)** port = 0..1, sets pull-up for 8 channels at once.
|
||||
- **bool getPullup8(uint8_t port, uint8_t &mask)** port = 0..1, reads pull-up for 8 channels at once.
|
||||
|
||||
|
||||
### 16 pins interface
|
||||
|
||||
- **bool pinMode16(uint16_t value)** value = 0..0xFFFF, returns true if successful.
|
||||
- **bool write16(uint16_t value)** value = 0..0xFFFF, returns true if successful.
|
||||
- **uint16_t read16()** reads 16 pins into an uint16_t.
|
||||
- **bool setPolarity16(uint16_t mask)** sets polarity for 16 channels.
|
||||
- **bool getPolarity16(uint16_t &mask)** reads polarity of 16 channels.
|
||||
- **bool setPullup16(uint16_t mask)** sets pull-up for 16 channels.
|
||||
- **bool getPullup16(uint16_t &mask)** reads pull-up for 16 channels.
|
||||
|
||||
|
||||
### Error codes
|
||||
|
||||
- **int lastError()** Above functions set an error flag that can be read with this function.
|
||||
@ -73,4 +84,4 @@ See examples.
|
||||
## Future
|
||||
|
||||
- keep functional in sync with MCP23017_RT
|
||||
|
||||
- **isConnected()** is not really needed
|
||||
|
@ -86,8 +86,29 @@ void setup()
|
||||
Serial.print("TEST read8(port):\t");
|
||||
delay(100);
|
||||
start = micros();
|
||||
volatile int val = MCP.read8(0);
|
||||
val = MCP.read8(1);
|
||||
volatile int val8 = MCP.read8(0);
|
||||
val8 = MCP.read8(1);
|
||||
stop = micros();
|
||||
Serial.println((stop - start) / 2.0);
|
||||
Serial.println();
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
//
|
||||
// write16 read16 interface
|
||||
//
|
||||
Serial.print("TEST write16(mask):\t");
|
||||
delay(100);
|
||||
start = micros();
|
||||
MCP.write16(0xAAAA); // alternating HIGH/LOW
|
||||
stop = micros();
|
||||
Serial.println((stop - start) / 2.0);
|
||||
|
||||
|
||||
Serial.print("TEST read16():\t");
|
||||
delay(100);
|
||||
start = micros();
|
||||
volatile uint16_t val16 = MCP.read16();
|
||||
stop = micros();
|
||||
Serial.println((stop - start) / 2.0);
|
||||
Serial.println();
|
||||
@ -102,4 +123,3 @@ void loop()
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
# Performance test
|
||||
|
||||
Test sketch MCP23S17_performance.ino
|
||||
|
||||
Max clock frequency 10 MHz, for an UNO this is 8 MHz (divider of CPU clock)
|
||||
|
||||
### Library version: 0.1.1
|
||||
|
||||
| Action | SW SPI | HW 1 MHz | HW 2 MHz | HW 4 MHz | HW 8 MHz | notes |
|
||||
|:------------------------------|--------:|---------:|---------:|---------:|---------:|:---------:|
|
||||
| TEST digitalWrite(0, value) | 892.25 | 87.75 | 64.00 | 52.25 | 46.25 |
|
||||
| TEST digitalWrite(pin, value) | 893.75 | 89.75 | 65.25 | 53.00 | 47.50 |
|
||||
| TEST digitalRead(pin) | 447.75 | 44.75 | 32.75 | 26.75 | 24.25 |
|
||||
| | | | | | |
|
||||
| TEST write8(port, mask) | 446.00 | 44.00 | 32.00 | 26.00 | 22.00 |
|
||||
| TEST read8(port) | 446.00 | 44.00 | 32.00 | 26.00 | 22.00 |
|
||||
| TEST write16(mask) | 446.00 | 46.00 | 34.00 | 28.00 | 22.00 | since 0.1.1
|
||||
| TEST read16() | 446.00 | 44.00 | 32.00 | 26.00 | 22.00 | since 0.1.1
|
||||
|
||||
|
||||
|
||||
### Notes
|
||||
|
||||
Performance as expected.
|
||||
|
||||
|
||||
### Future
|
||||
|
||||
- test ESP32 and other platforms
|
||||
- register based IO version for the SW SPI on AVR ?
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/MCP23S17.git"
|
||||
},
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=MCP23S17
|
||||
version=0.1.0
|
||||
version=0.1.1
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for SPI MCP23S17 16 channel port expander 16 IO-lines
|
||||
|
Loading…
Reference in New Issue
Block a user