Skip to content

Commit

Permalink
sync with TCA9554
Browse files Browse the repository at this point in the history
  • Loading branch information
RobTillaart committed Jan 9, 2025
1 parent 68af41f commit 9b79bc9
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 63 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.3.3] - 2025-01-09
- sync with TCA9554
- add keywords.txt
- fix interrupt example


## [0.3.2] - 2024-03-11
- Fix #18, pinMode in examples (kudos to nerdyscout)
- update GitHub actions to v4
Expand All @@ -14,7 +20,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- add datasheet to repo
- minor edits


## [0.3.1] - 2024-01-06
- minor edits

Expand Down
66 changes: 36 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Note that for the 16 bit interface settings are not perfectly simultaneous
as the 16 bit interface does in fact 2 calls to the 8 bit interface.


#### TCA9535
### TCA9535

From datasheet:

Expand All @@ -38,7 +38,29 @@ There is a TCA9535 class which is a (convenience) wrapper around the TCA9555 cla
This allows one to create TCA9535 objects.


#### 0.3.0 Breaking change
### Compatibles

The library is expected to work for the PCA9554 / PCA9534 too. To be verified (feedback welcome).


### Related

16 bit port expanders

- https://github.com/RobTillaart/MCP23017_RT
- https://github.com/RobTillaart/MCP23S17 (SPI)
- https://github.com/RobTillaart/PCF8575
- https://github.com/RobTillaart/PCA9555

8 bit port expanders

- https://github.com/RobTillaart/MCP23008
- https://github.com/RobTillaart/MCP23S08 (SPI)
- https://github.com/RobTillaart/PCF8574
- https://github.com/RobTillaart/PCA9554


### 0.3.0 Breaking change

The version 0.3.0 has breaking changes in the interface.
The rationale is that the programming environment of the **Arduino ESP32 S3**
Expand All @@ -60,8 +82,7 @@ The following library functions have been renamed:
| digitalWrite() | write1() |



#### 0.2.0 Breaking change
### 0.2.0 Breaking change

Version 0.2.0 introduced a breaking change.
You cannot set the pins in **begin()** any more.
Expand All @@ -70,32 +91,17 @@ The user has to call **Wire.begin()** and can optionally set the Wire pins
before calling **begin()**.


#### Related

16 bit port expanders

- https://github.com/RobTillaart/MCP23017_RT
- https://github.com/RobTillaart/MCP23S17
- https://github.com/RobTillaart/PCF8575

8 bit port expanders

- https://github.com/RobTillaart/MCP23008
- https://github.com/RobTillaart/MCP23S08
- https://github.com/RobTillaart/PCF8574


## Hardware

#### I2C addresses
### I2C addresses

The addresses for the TCA9555 and TCA9535 are 0x20..0x27.
These are to be set with pin A0, A1, A2.

Both the TCA9555 and TCA9535 support up to 400 kHz I2C.


#### I2C multiplexing
### I2C multiplexing

Sometimes you need to control more devices than possible with the default
address range the device provides.
Expand All @@ -113,7 +119,7 @@ too if they are behind the multiplexer.
- https://github.com/RobTillaart/TCA9548


#### INT
### INT pin interrupts

The interrupt pin is not supported by the library.
Needs investigation (+ examples).
Expand Down Expand Up @@ -145,13 +151,13 @@ Returns true if device can be seen on I2C bus, false otherwise.
- **bool write1(uint8_t pin, uint8_t value)** pin = 0..15, value = LOW(0) HIGH (!0), returns true if successful.
- **uint8_t read1(uint8_t pin)** pin = 0..15, returns the value of the pin HIGH or LOW.
- **bool setPolarity(uint8_t pin, uint8_t value)** inverts polarity of an INPUT pin.
- **uint8_t getPolarity(uint8_t pin)** returns 1 if a pin is inverted.
- **uint8_t getPolarity(uint8_t pin)** returns 1 if a pin is inverted, zero otherwise.


#### 8 pin interface
### 8 pin interface

port = 0..1
mask = 0..255
mask = 0..255 (0xFF)

- **bool pinMode8(uint8_t port, uint8_t mask)** set the mode of eight pins in one call.
- **bool write8(uint8_t port, uint8_t mask)** returns true if successful.
Expand All @@ -161,7 +167,7 @@ Especially useful if one needs to trigger multiple pins at the exact same time.
- **uint8_t getPolarity(uint8_t port)** returns a mask with a 1 for every INPUT pin that is inverted.


#### 16 pin interface
### 16 pin interface

Be aware that the 16 pins interface does two calls to the 8 pins interface.
So it is impossible to switch pins from the 2 groups of 8 at exactly the same time
Expand All @@ -175,7 +181,7 @@ Returns true upon success.
- **uint16_t getPolarity()** returns a mask of 16 bits with a 1 for every INPUT pin that is inverted.


#### Error codes
### Error codes

- **int lastError()** Above functions set an error flag that can be read with this function.
Reading it will reset the flag to **TCA9555_OK**.
Expand All @@ -193,14 +199,13 @@ Reading it will reset the flag to **TCA9555_OK**.

## Future


#### Must

- update documentation
- buy TCA9555 / TCA9535
- buy TCA9555 / TCA9535 / PCA9555 / PCA9535
- test all functionality
- library is written without hardware

- keep TCA9554/TCA9555 in sync

#### Should

Expand All @@ -216,6 +221,7 @@ Reading it will reset the flag to **TCA9555_OK**.

#### Could

- add PCA9555/35 as derived class.
- rethink class hierarchy
- TCA9535 has less functions so should be base class
- add performance example for I2C.
Expand Down
69 changes: 46 additions & 23 deletions TCA9555.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// FILE: TCA9555.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.3.2
// VERSION: 0.3.3
// PURPOSE: Arduino library for I2C TCA9555 16 channel port expander
// DATE: 2021-06-09
// URL: https://github.com/RobTillaart/TCA9555
Expand Down Expand Up @@ -30,10 +30,18 @@ TCA9555::TCA9555(uint8_t address, TwoWire *wire)
}


bool TCA9555::begin()
bool TCA9555::begin(bool mode, uint16_t mask)
{
if ((_address < 0x20) || (_address > 0x27)) return false;
if (! isConnected()) return false;

if (mode == OUTPUT)
{
pinMode16(0x0000);
write16(mask);
} else {
pinMode16(0xFFFF);
}
return true;
}

Expand All @@ -55,7 +63,7 @@ uint8_t TCA9555::getAddress()
//
// 1 PIN INTERFACE
//
bool TCA9555::pinMode1(uint8_t pin, uint8_t mode) // pin = 0..15
bool TCA9555::pinMode1(uint8_t pin, uint8_t mode)
{
if (pin > 15)
{
Expand All @@ -74,16 +82,20 @@ bool TCA9555::pinMode1(uint8_t pin, uint8_t mode) // pin = 0..15
pin -= 8;
}
uint8_t val = readRegister(CONFREG);
uint8_t prevVal = val;
uint8_t mask = 1 << pin;
if (mode == INPUT) val |= mask;
if (mode == OUTPUT) val &= ~mask;
writeRegister(CONFREG, val);
else val &= ~mask;
if (val != prevVal)
{
writeRegister(CONFREG, val);
}
_error = TCA9555_OK;
return true;
}


bool TCA9555::write1(uint8_t pin, uint8_t value) // pin = 0..15
bool TCA9555::write1(uint8_t pin, uint8_t value)
{
if (pin > 15)
{
Expand All @@ -97,10 +109,14 @@ bool TCA9555::write1(uint8_t pin, uint8_t value) // pin = 0..15
pin -= 8;
}
uint8_t val = readRegister(OPR);
uint8_t prevVal = val;
uint8_t mask = 1 << pin;
if (value) val |= mask;
else val &= ~mask;
writeRegister(OPR, val);
if (value) val |= mask; // all values are HIGH.
else val &= ~mask;
if (val != prevVal)
{
writeRegister(OPR, val);
}
_error = TCA9555_OK;
return true;
}
Expand All @@ -127,24 +143,33 @@ uint8_t TCA9555::read1(uint8_t pin) // pin = 0..15
}


bool TCA9555::setPolarity(uint8_t pin, uint8_t value) // pin = 0..15
bool TCA9555::setPolarity(uint8_t pin, uint8_t value)
{
if (pin > 15)
{
_error = TCA9555_PIN_ERROR;
return false;
}
if ((value != LOW) && (value != HIGH))
{
_error = TCA9555_VALUE_ERROR;
return false;
}
uint8_t POLREG = TCA9555_POLARITY_REGISTER_0;
if (pin > 7)
{
POLREG = TCA9555_POLARITY_REGISTER_1;
pin -= 8;
}
uint8_t val = readRegister(POLREG);
uint8_t prevVal = val;
uint8_t mask = 1 << pin;
if (value == HIGH) val |= mask;
if (value == LOW) val &= ~mask;
writeRegister(POLREG, val);
else val &= ~mask;
if (val != prevVal)
{
writeRegister(POLREG, val);
}
_error = TCA9555_OK;
return true;
}
Expand All @@ -165,7 +190,6 @@ uint8_t TCA9555::getPolarity(uint8_t pin)
}



//////////////////////////////////////////////////////////
//
// 8 PIN INTERFACE
Expand All @@ -179,8 +203,7 @@ bool TCA9555::pinMode8(uint8_t port, uint8_t mask)
}
_error = TCA9555_OK;
if (port == 0) return writeRegister(TCA9555_CONFIGURATION_PORT_0, mask);
if (port == 1) return writeRegister(TCA9555_CONFIGURATION_PORT_1, mask);
return false;
return writeRegister(TCA9555_CONFIGURATION_PORT_1, mask);
}


Expand All @@ -193,8 +216,7 @@ bool TCA9555::write8(uint8_t port, uint8_t mask) // port = 0..1
}
_error = TCA9555_OK;
if (port == 0) return writeRegister(TCA9555_OUTPUT_PORT_REGISTER_0, mask);
if (port == 1) return writeRegister(TCA9555_OUTPUT_PORT_REGISTER_1, mask);
return false;
return writeRegister(TCA9555_OUTPUT_PORT_REGISTER_1, mask);
}


Expand All @@ -207,8 +229,7 @@ int TCA9555::read8(uint8_t port)
}
_error = TCA9555_OK;
if (port == 0) return readRegister(TCA9555_INPUT_PORT_REGISTER_0);
if (port == 1) return readRegister(TCA9555_INPUT_PORT_REGISTER_1);
return 0; // keeps compiler happy
return readRegister(TCA9555_INPUT_PORT_REGISTER_1);
}


Expand All @@ -221,8 +242,7 @@ bool TCA9555::setPolarity8(uint8_t port, uint8_t mask)
}
_error = TCA9555_OK;
if (port == 0) return writeRegister(TCA9555_POLARITY_REGISTER_0, mask);
if (port == 1) return writeRegister(TCA9555_POLARITY_REGISTER_1, mask);
return false;
return writeRegister(TCA9555_POLARITY_REGISTER_1, mask);
}


Expand All @@ -235,8 +255,7 @@ uint8_t TCA9555::getPolarity8(uint8_t port)
}
_error = TCA9555_OK;
if (port == 0) return readRegister(TCA9555_POLARITY_REGISTER_0);
if (port == 1) return readRegister(TCA9555_POLARITY_REGISTER_1);
return 0; // keeps compiler happy
return readRegister(TCA9555_POLARITY_REGISTER_1);
}


Expand Down Expand Up @@ -289,6 +308,10 @@ uint8_t TCA9555::getPolarity16()
}


//////////////////////////////////////////////////////////
//
// OTHER
//
int TCA9555::lastError()
{
int error = _error;
Expand Down
7 changes: 4 additions & 3 deletions TCA9555.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// FILE: TCA9555.h
// AUTHOR: Rob Tillaart
// VERSION: 0.3.2
// VERSION: 0.3.3
// PURPOSE: Arduino library for I2C TCA9555 16 channel port expander
// DATE: 2021-06-09
// URL: https://github.com/RobTillaart/TCA9555
Expand All @@ -12,7 +12,7 @@
#include "Wire.h"


#define TCA9555_LIB_VERSION (F("0.3.2"))
#define TCA9555_LIB_VERSION (F("0.3.3"))

#define TCA9555_OK 0x00
#define TCA9555_PIN_ERROR 0x81
Expand Down Expand Up @@ -51,7 +51,7 @@ class TCA9555
public:
TCA9555(uint8_t address, TwoWire *wire = &Wire);

bool begin();
bool begin(bool mode = INPUT, uint16_t mask = 0x0000);
bool isConnected();
uint8_t getAddress();

Expand Down Expand Up @@ -89,6 +89,7 @@ class TCA9555
uint8_t getPolarity16();


// OTHER
int lastError();
uint8_t getType();

Expand Down
Loading

0 comments on commit 9b79bc9

Please sign in to comment.