mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-09-19 16:46:11 -04:00
0.1.4 TCA9548
This commit is contained in:
parent
7a8b13bd8c
commit
231275ad75
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 --
|
||||
|
||||
|
@ -18,6 +18,10 @@ getChannelMask KEYWORD2
|
||||
|
||||
setResetPin KEYWORD2
|
||||
reset KEYWORD2
|
||||
|
||||
setForced KEYWORD2
|
||||
getForced KEYWORD2
|
||||
|
||||
getError KEYWORD2
|
||||
|
||||
|
||||
|
@ -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": "*",
|
||||
|
@ -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=*
|
||||
|
@ -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 --
|
Loading…
Reference in New Issue
Block a user