0.1.4 TCA9548

This commit is contained in:
rob tillaart 2023-01-23 16:36:29 +01:00
parent 7a8b13bd8c
commit 231275ad75
13 changed files with 136 additions and 70 deletions

View File

@ -6,7 +6,7 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: arduino/arduino-lint-action@v1
with:
library-manager: update

View File

@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6

View File

@ -10,7 +10,7 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: json-syntax-check
uses: limitusus/json-syntax-check@v1
with:

View File

@ -6,13 +6,22 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.1.4] - 2023-01-23
- update GitHub actions
- update license 2023
- update readme.md
- update keywords.txt
- add **void disableAllChannels()**
- all channel functions return bool, true on success.
- minor edits
## [0.1.3] - 2022-11-26
- Add RP2040 support to build-CI.
- Add CHANGELOG.md
- update readme.md
- move code to .cpp
## [0.1.2] - 2021-12-28
- update license
- minor edits

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2021 - 2022 Rob Tillaart
Copyright (c) 2021-2023 Rob Tillaart
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -13,7 +13,8 @@ Arduino Library for TCA9548 I2C multiplexer.
## Description
Library for the TCA9548 and TCA9548a I2C multiplexer.
Library for the TCA9548 and TCA9548a (PCA9548, PCA9548a) I2C multiplexer.
The library allows you to enable 0 to 7 I2C channels (ports) uniquely or simultaneously.
This is especially useful if you have multiple devices/sensors that have a fixed address,
or you have address conflicts between I2C devices
@ -21,50 +22,80 @@ or you have address conflicts between I2C devices
**Warning**
The library is not tested extensively.
I2C address is 0x70 .. 0x77.
I2C address of the device itself is 0x70 .. 0x77.
This address may not be used on any of the I2C channels of course.
The library caches the channels enabled, and if a channel is enabled,
it will not be enabled again (low level) to optimize performance.
#### Compatible devices
This library is expected to work for the PCA9548(a) too as the TCA is pin compatible newer version.
| Device | Tested | Notes |
|:-----------|:--------:|:-------:|
| TCA9548s | n |
| PCA9548 | n | see links below |
| PCA9548a | n |
There are however small differences, check the datasheets to see the details.
- [difference TCA PCA](https://e2e.ti.com/support/interface-group/interface/f/interface-forum/815758/faq-what-is-the-difference-between-an-i2c-device-with-the-family-name-pca-and-tca)
- https://electronics.stackexchange.com/questions/209616/is-nxps-pca9548a-compatible-with-tis-tca9548a
- https://www.nxp.com/docs/en/application-note/AN262.pdf
## Interface
```cpp
#include "TCA9548.h"
```
### Constructor
#### Constructor
- **TCA9548(const uint8_t deviceAddress, TwoWire \*wire = &Wire)** Constructor, address = 0x70 .. 0x77, wire = Wire or WireN.
- **bool begin(uint8_t sda, uint8_t scl, uint8_t mask = 0x00)** Set I2C pins for ESP32, set mask of channels to be enabled.
- **bool begin(uint8_t mask = 0x00)** set mask of channels to be enabled.
- **TCA9548(const uint8_t deviceAddress, TwoWire \*wire = &Wire)** Constructor.
deviceAddress = 0x70 .. 0x77, wire = Wire or WireN.
- **bool begin(uint8_t dataPin, uint8_t clockPin, uint8_t mask = 0x00)** Set I2C pins for ESP32.
Set mask of channels to be enabled, default all disabled.
- **bool begin(uint8_t mask = 0x00)** set mask of channels to be enabled, default all disabled.
- **bool isConnected()** returns true if address of the multiplexer is found on I2C bus.
### Find device
#### Find device
- **bool isConnected(uint8_t address)** returns true if arbitrary address is found on I2C bus.
This can be used to verify a certain device is available (or not) on an enabled channel.
### Channel functions
#### Channel functions
- **void enableChannel(uint8_t channel)** enables channel 0 .. 7 non-exclusive.
All "channel functions" return true on success.
- **bool enableChannel(uint8_t channel)** enables channel 0 .. 7 non-exclusive.
Multiple channels can be enabled in parallel.
- **void disableChannel(uint8_t channel)** disables channel 0 .. 7.
- **bool disableChannel(uint8_t channel)** disables channel 0 .. 7.
Will not disable other channels.
- **void selectChannel(uint8_t channel)** enables a single channel 0 .. 7 exclusive.
- **bool selectChannel(uint8_t channel)** enables a single channel 0 .. 7 exclusive.
All other channels will be disabled in the same call, so not before or after.
- **bool isEnabled(uint8_t channel)** returns true if the channel is enabled.
- **void setChannelMask(uint8_t mask)** enables 0 or more channels simultaneously with a bit mask.
- **bool disableAllChannels()** fast way to disable all.
- **bool setChannelMask(uint8_t mask)** enables 0 or more channels simultaneously with a bit mask.
- **uint8_t getChannelMask()** reads back the bit mask of the channels enabled.
#### Reset
- **void setResetPin(uint8_t resetPin)** sets the pin to reset the chip. (Not tested)
- **void reset()** trigger the reset pin.
- **int getError()** returns the last I2C error.
### Forced IO
#### Forced IO
When forced IO is set all writes and read - **getChannelMask()** - will go to the device.
If the flag is set to false it will cache the value of the channels enabled.
This will result in more responsive / faster calls.
This will result in more responsive / faster calls.
Note that writes are only optimized if the channels are already set.
- **void setForced(bool forced = false)** set forced write, slower but more robust.
@ -73,25 +104,30 @@ Note that writes are only optimized if the channels are already set.
- **bool getForced()** returns set flag.
## Operation
See example
## Future
#### must
- improve documentation.
- improve error handling
#### Must
- improve documentation.
- improve error handling
#### Should
#### should
- add examples
- test test and test
- write unit test
- add **disableAll()** == setChannelMask(0)
- create derived classes for compatible devices
#### Could
#### could
- set an "always enabled" mask (have to investigate the consequences)
- check PCA9548 compatibility
- verify channel in range
- e.g. **bool enableChannel(uint8_t channel)**, disable(), select()
#### Wont

View File

@ -1,7 +1,7 @@
//
// FILE: TCA9548.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.3
// VERSION: 0.1.4
// DATE: 2021-03-16
// PURPOSE: Library for TCA9548 I2C multiplexer
@ -60,23 +60,33 @@ bool TCA9548::isConnected(uint8_t address)
void TCA9548::enableChannel(uint8_t channel)
bool TCA9548::enableChannel(uint8_t channel)
{
if (isEnabled(channel)) return;
setChannelMask(_mask | (0x01 << channel));
if (channel > 7) return false;
if (!isEnabled(channel))
{
setChannelMask(_mask | (0x01 << channel));
}
return true;
}
void TCA9548::disableChannel(uint8_t channel)
bool TCA9548::disableChannel(uint8_t channel)
{
if (!isEnabled(channel)) return;
setChannelMask(_mask & ~(0x01 << channel));
if (channel > 7) return false;
if (!isEnabled(channel))
{
setChannelMask(_mask & ~(0x01 << channel));
}
return true;
}
void TCA9548::selectChannel(uint8_t channel)
bool TCA9548::selectChannel(uint8_t channel)
{
if (channel > 7) return false;
setChannelMask(0x01 << channel);
return true;
}
@ -87,13 +97,20 @@ bool TCA9548::isEnabled(uint8_t channel)
}
void TCA9548::setChannelMask(uint8_t mask)
bool TCA9548::disableAllChannels()
{
if ((_mask == mask) && (! _forced)) return;
return setChannelMask(0x00);
}
bool TCA9548::setChannelMask(uint8_t mask)
{
if ((_mask == mask) && (! _forced)) return true;
_mask = mask;
_wire->beginTransmission(_address);
_wire->write(_mask);
_error = _wire->endTransmission();
return (_error == 0);
}
@ -124,15 +141,15 @@ void TCA9548::reset()
}
void TCA9548::setForced(bool forced)
{
_forced = forced;
void TCA9548::setForced(bool forced)
{
_forced = forced;
};
bool TCA9548::getForced()
{
return _forced;
bool TCA9548::getForced()
{
return _forced;
};

View File

@ -2,45 +2,45 @@
//
// FILE: TCA9548.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.3
// VERSION: 0.1.4
// DATE: 2021-03-16
// PURPOSE: Library for TCA9548 I2C multiplexer
//
// URL: https://github.com/RobTillaart/TCA9548
//
#include "Arduino.h"
#include "Wire.h"
#define TCA9548_LIB_VERSION (F("0.1.3"))
#define TCA9548_LIB_VERSION (F("0.1.4"))
class TCA9548
{
public:
// address = 0x70 .. 0x77
// deviceAddress = 0x70 .. 0x77
TCA9548(const uint8_t deviceAddress, TwoWire *wire = &Wire);
#if defined (ESP8266) || defined(ESP32)
bool begin(uint8_t sda, uint8_t scl, uint8_t mask = 0x00); // default no channels enabled
bool begin(uint8_t dataPin, uint8_t clockPin, uint8_t mask = 0x00); // default no channels enabled
#endif
bool begin(uint8_t mask = 0x00); // default no channels enabled
bool isConnected(); // find multiplexer on I2C bus
bool isConnected(uint8_t address); // find any address on I2C bus
// channel = 0.. 7
void enableChannel(uint8_t channel); // enable this channel non exclusive
void disableChannel(uint8_t channel);
void selectChannel(uint8_t channel); // enable only this channel
bool enableChannel(uint8_t channel); // enable this channel non exclusive
bool disableChannel(uint8_t channel);
bool selectChannel(uint8_t channel); // enable only this channel
bool isEnabled(uint8_t channel);
bool disableAllChannels();
// mask = 0x00 .. 0xFF - every bit is a channel.
// note these are set simultaneously.
void setChannelMask(uint8_t mask);
bool setChannelMask(uint8_t mask);
uint8_t getChannelMask();
// reset
void setResetPin(uint8_t resetPin);
void reset(); // trigger reset pin
@ -50,13 +50,14 @@ public:
int getError();
private:
uint8_t _mask; // caching mask = status of channels
uint8_t _resetPin; // default not set == -1 (255)
int _error;
uint8_t _address;
TwoWire* _wire;
uint8_t _mask; // caching mask = status of channels
uint8_t _resetPin; // default not set == -1 (255)
bool _forced;
int _error;
};

View File

@ -2,7 +2,6 @@
// FILE: tca9548_demo.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo TCA9548 I2C multiplexer
// DATE: 2021-03-16
// URL: https://github.com/RobTillaart/TCA9548
@ -65,5 +64,5 @@ void loop()
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -18,6 +18,10 @@ getChannelMask KEYWORD2
setResetPin KEYWORD2
reset KEYWORD2
setForced KEYWORD2
getForced KEYWORD2
getError KEYWORD2

View File

@ -1,6 +1,6 @@
{
"name": "TCA9548",
"keywords": "TCA9548,TCA9548a,I2C,multiplexer",
"keywords": "TCA9548,TCA9548a,PCA9548,PCA9548a,I2C,multiplexer",
"description": "Arduino Library for TCA9548 I2C multiplexer.",
"authors":
[
@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/TCA9548"
},
"version": "0.1.3",
"version": "0.1.4",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",

View File

@ -1,9 +1,9 @@
name=TCA9548
version=0.1.3
version=0.1.4
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino Library for TCA9548 I2C multiplexer.
paragraph=
paragraph=TCA9548, TCA9548a, PCA9548, PCA9548a
category=Signal Input/Output
url=https://github.com/RobTillaart/TCA9548
architectures=*

View File

@ -31,10 +31,10 @@
// assertNotNAN(arg); // !isnan(a)
/*
most unit tests will test for fail
most unit tests will test for fail
as there is no sensor connected
and there is no mockup.
It appears that Wire.write does not fail without sensor...
*/
@ -45,7 +45,7 @@
#include "TCA9548.h"
int expect; // TODO needed as there seems a problem with 8 bit comparisons (char?)
int expect; // TODO needed as there seems a problem with 8 bit comparisons (char?)
uint32_t start, stop;
@ -113,4 +113,4 @@ unittest(test_select)
unittest_main()
// --------
// -- END OF FILE --