You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The TCA9548A takes an input I2C bus and splits it into up to eight more I2C buses! We use this for two reasons:
Allowing us to repetitively use the same I2C devices without having to set unique addresses on all of them (see all the sensors on each solar panel!)
Providing some level of bus protection, so the primary I2C bus is insulated from failures of downstream devices (i.e. if we lose a temp sensor on one solar panel face it shouldn't block getting data from all other solar panel faces)
Beware that this device (or at least the CIrcuitPython implementation of it!) is pretty finicky though and will unexpectedly hang the code if not initialized correctly. See the #25 Cube Killer on the CircuitPython repo for an example of this.
This component should:
Initialize the Sensor
Facilitate the creation of mux'd I2C buses and pass those through to other components
Allow for the deint / reint of the daughter I2C buses when needed
The way the TCA works kinda interesting in that the driver for this device is just a nested I2C driver. As in what you do is you send to an I2C address a port and another I2C address with whatever nested command you want to be passed through. If this is confusing I can try to make a diagram that describes this behavior.
This development effort might go hand in hand with the creation of a custom I2C driver for fprime-proves.
Example CircuitPython Implementation
From the tea9548a.py
importtimefrommicropythonimportconsttry:
fromtypingimportListfromtyping_extensionsimportLiteralfromcircuitpython_typingimportWriteableBuffer, ReadableBufferfrombusioimportI2CexceptImportError:
pass_DEFAULT_ADDRESS=const(0x70)
__version__="0.0.0+auto.0"__repo__="https://github.com/adafruit/Adafruit_CircuitPython_TCA9548A.git"classTCA9548A_Channel:
"""Helper class to represent an output channel on the TCA9548A and take care of the necessary I2C commands for channel switching. This class needs to behave like an I2CDevice."""def__init__(self, tca: "TCA9548A", channel: int) ->None:
self.tca=tcaself.channel_switch=bytearray([1<<channel])
deftry_lock(self) ->bool:
"""Pass through for try_lock."""whilenotself.tca.i2c.try_lock():
time.sleep(0)
self.tca.i2c.writeto(self.tca.address, self.channel_switch)
returnTruedefunlock(self) ->bool:
"""Pass through for unlock."""self.tca.i2c.writeto(self.tca.address, b"\x00")
returnself.tca.i2c.unlock()
defreadfrom_into(self, address: int, buffer: ReadableBuffer, **kwargs):
"""Pass through for readfrom_into."""ifaddress==self.tca.address:
raiseValueError("Device address must be different than TCA9548A address.")
returnself.tca.i2c.readfrom_into(address, buffer, **kwargs)
defwriteto(self, address: int, buffer: WriteableBuffer, **kwargs):
"""Pass through for writeto."""ifaddress==self.tca.address:
raiseValueError("Device address must be different than TCA9548A address.")
returnself.tca.i2c.writeto(address, buffer, **kwargs)
defwriteto_then_readfrom(
self,
address: int,
buffer_out: WriteableBuffer,
buffer_in: ReadableBuffer,
**kwargs
):
"""Pass through for writeto_then_readfrom."""# In linux, at least, this is a special kernel function callifaddress==self.tca.address:
raiseValueError("Device address must be different than TCA9548A address.")
returnself.tca.i2c.writeto_then_readfrom(
address, buffer_out, buffer_in, **kwargs
)
defscan(self) ->List[int]:
"""Perform an I2C Device Scan"""returnself.tca.i2c.scan()
classTCA9548A:
"""Class which provides interface to TCA9548A I2C multiplexer."""def__init__(self, i2c: I2C, address: int=_DEFAULT_ADDRESS) ->None:
self.i2c=i2cself.address=addressself.channels= [None] *8def__len__(self) ->Literal[8]:
return8def__getitem__(self, key: Literal[0, 1, 2, 3, 4, 5, 6, 7]) ->"TCA9548A_Channel":
ifnot0<=key<=7:
raiseIndexError("Channel must be an integer in the range: 0-7.")
ifself.channels[key] isNone:
self.channels[key] =TCA9548A_Channel(self, key)
returnself.channels[key]
What Does This Component Do?
The TCA9548A takes an input I2C bus and splits it into up to eight more I2C buses! We use this for two reasons:
Beware that this device (or at least the CIrcuitPython implementation of it!) is pretty finicky though and will unexpectedly hang the code if not initialized correctly. See the #25 Cube Killer on the CircuitPython repo for an example of this.
This component should:
Design Notes
TCA Datasheet
Adafruit TCA Guide
The way the TCA works kinda interesting in that the driver for this device is just a nested I2C driver. As in what you do is you send to an I2C address a port and another I2C address with whatever nested command you want to be passed through. If this is confusing I can try to make a diagram that describes this behavior.
This development effort might go hand in hand with the creation of a custom I2C driver for fprime-proves.
Example CircuitPython Implementation
From the
tea9548a.py
In the
pysquared.py
Reference Schematic
Mux Board V1 Schematic
Required Hardware
The text was updated successfully, but these errors were encountered: