I2C Multiplexer - Simple? - Page 1
Forum section: electronics / general

author: fourfathom
author_rank: Super Contributor
timestamp: May 26, 2023, 05:13:01 pm
content: I want to put two parts on a board that have the same I2C address. I could use a purpose-built I2C mux chip (such as the Texas Instruments TCA9548A), but is there any good reason why just using a pair of 2:1 analog muxes (like the SN74LVC1G3157 Single-Pole Double-Throw Analog Switch:https://www.ti.com/lit/ds/symlink/sn74lvc1g3157.pdf?ts=1685085821035) wouldn't work? I would need pull-ups on each of the output ports, but the layout would keep the mux-to-device traces very short. That mux shows about 30 Ohms max series resistance (with a 3V Vdd).Am I missing something? This would sure be cheap and easy. The on-board controller would select which device it wanted to talk to by switching the mux.

author: DavidAlfa
author_rank: Super Contributor
timestamp: May 26, 2023, 05:30:25 pm
content: Isn't obvious?Using analog switches need more I/O, additional Code/routines to do the switching and so on.The TCA is placed in the middle of the i2c bus, also talks i2c, so nothing else is required, will fit anywhere!It's easier to implement, just "send this data to this i2c address".Switching done!

author: schmitt trigger
author_rank: Super Contributor
timestamp: May 26, 2023, 06:26:16 pm
content: I personally haven’t done it, but I actually saw it in a commercial product.The key is that your switching device must have low “on” resistance. The regular CD40xx muxes have like 600 ohms at 5 volts. (This value is from my memory, please check the datasheet).

author: nctnico
author_rank: Super Contributor
timestamp: May 26, 2023, 06:59:38 pm
content: You can use an analog switch (like the 74HC(T)4067 for 16 channels) in the SDA line. I have done this is several designs. Make sure to add a pull-up (like 100k Ohm) to the SDA lines of each output so they stay high.

author: Infraviolet
author_rank: Super Contributor
timestamp: May 26, 2023, 07:55:16 pm
content: If you desperately wanted to control the multiplexer without needing extra IO lines, didn't want to have to interpret the datasheet of an existing I2C multiplexer and were willing to go with a multiple chip solution...You could always have non-i2c-specialised multiplexer chips for the two I2C lines, and have these multiplexers controlled from a small microcontroller (ATtiny85 or something equivalent). The microcontroller could watch the I2C lines for customised I2C commands you define and change the multiplexer's state accordingly, you could also program it to disconnect the multiplexer when these customised commands are arriving if they include any byte sequences which might be read and misinterpreted by any existing I2C slave devices beyond the multiplexing area.

author: fourfathom
author_rank: Super Contributor
timestamp: May 26, 2023, 09:34:43 pm
content: To clarify, this is for a product where I write the code running on the board controller, including talking to the two (Si5351 clock generator) chips. I would use a controller I/O pin to control the mux.That mux I mentioned has worst-case channel resistance of 30 Ohms, and compared to the typical I2C pull-up resistors seems like not much of an issue. There will only be the controller, mux, and the two clock-generators on the I2C bus, and the traces will be short, so the capacitance should be minimal. I can put a strong pull-up at the controller end, and much weaker pullups at the slave device ends.Quote from: nctnico on May 26, 2023, 06:59:38 pmWhen looking at the I2C spec, it seemed that because of potential clock-stretching (where the slave holds the clock line low) I would need bidirectional muxes on both SDA and SCL. Is this not necessary? Actually, I suppose not, since the unselected device will never see the SDA transitions and so never try to stretch the clock. Correct?

author: nctnico
author_rank: Super Contributor
timestamp: May 26, 2023, 10:03:22 pm
content: You'll need to use bi-directional switches on SDA because the device will also pull the SDA line low. Using an analog switch is the simplest method and the single gate swithes are super cheap anyway.Since I2C uses both SCL and SDA for start / stop conditions, the unselected/ unconnected device won't see a start / stop condition and won't become active.

author: tom66
author_rank: Super Contributor
timestamp: May 26, 2023, 10:48:55 pm
content: One issue with a multiplexer is if you don't have pure software control over your I2C bus (for instance, it's bytes that are output by an I2C module) you could accidentally switch it mid-transaction, which would likely leave you with a broken bus.It's for this reason I quite like the PCA9546A and friends: these are I2C bus switches but are addressed and controlled by the same bus. You write a register-then-value to the device to switch the downstream bus, and it only switches at the end of the transaction. They're dirt cheap and made by both NXP and TI. They do require pull ups on both sides of the bus, as the switch initialises with all channels off. It's also possible to have more than one downstream bus active for cases where that's useful.

author: fourfathom
author_rank: Super Contributor
timestamp: May 26, 2023, 10:55:10 pm
content: Quote from: nctnico on May 26, 2023, 10:03:22 pmThanks for simplifying my proposed solution by a factor of two! I'm going to try that little mux I mentioned (less than 8 cents ea, in a tiny SC-70-6 package) on this new design.

author: fourfathom
author_rank: Super Contributor
timestamp: May 26, 2023, 11:06:40 pm
content: Quote from: tom66 on May 26, 2023, 10:48:55 pmExcellent points, but in my particular case I am accessing the two I2C devices inside of a tightly-timed ISR, where I cycle through all the I2C accesses I need to do and there's a well-defined timing deadband between device accesses. For this reason there should be no issue of collision. At least looking at the I2C bus activity doesn't show enough timing variation to matter. I definitely wouldn't try this in a more general-purpose design.Yes, I looked at the PCA9546A, and it's certainly cheap enough for this application, but the additional I2C traffic needed to set up the mux would slow down my available clock generator update rate more than I would prefer (I think).

author: tom66
author_rank: Super Contributor
timestamp: May 26, 2023, 11:18:15 pm
content: Quote from: fourfathom on May 26, 2023, 11:06:40 pmIf it's not clear from the datasheet, the '9546A is latching: you write the configuration, and it will keep that channel enabled until reset. You do not need to prepend every transaction with a channel selection. You only need to do that if the channel has to change. So it depends on the application as to whether the extra 2 bytes would be problematic or not.

author: jwet
author_rank: Frequent Contributor
timestamp: May 27, 2023, 12:17:40 am
content: Maxim had several app notes on this. You don't need particularly fancy swtiches or anything. Pullups are usually 1k to 10K, your Ron just needs to much less than this- 100 ohms- not difficult. This was a common application for Maxim's small analog switches in all kinds of equipment. Sometimes it was because a customer wanted to use a bunch of the same I2C part. There are several common conflicting I2C addresses and this keeps you from having to bit bang i2C, difficult. Big I2C EEPROM were address hogs and conflicted with common RTC's like the DS1302. Have fun.

author: NiHaoMike
author_rank: Super Contributor
timestamp: May 27, 2023, 01:40:56 pm
content: I assume the microcontroller you're using either doesn't have another I2C controller or it's already in use elsewhere?

author: jwet
author_rank: Frequent Contributor
timestamp: May 27, 2023, 04:49:07 pm
content: Also, you only need to do it on one line- the Data line IIRC. You just have to keep from creating a start condition.

author: tom66
author_rank: Super Contributor
timestamp: May 27, 2023, 11:23:29 pm
content: Quote from: jwet on May 27, 2023, 04:49:07 pmIf you have any slaves that clock stretch, you definitely need to do the muxing on all signals.

author: nctnico
author_rank: Super Contributor
timestamp: May 27, 2023, 11:45:11 pm
content: Quote from: tom66 on May 27, 2023, 11:23:29 pmNo! Absolutely not. Clock stretch can only happen during an active transaction with a device by that device. With a mux in the SDA lines, the other device will not even see an active transaction and hence not stretch the clock either. It is the same as when a device on the same bus is not addressed, it will not stretch the clock.

author: Infraviolet
author_rank: Super Contributor
timestamp: May 28, 2023, 03:49:01 pm
content: "which would likely leave you with a broken bus"Useful trick, often 9 cycles of up and down on the clock line will force a slave to reset its I2C hardware, for well designed ones atleast.I'd always recommend, where feasible and if you have control of the design of the slave and the master, to include an extra digital line from master to a spare input pin on a slave (or a single one to pins on all slaves) where, after any crash/hang the master can tell the slaves to reset their I2C hardware to a known-good state before making any more transactions. This obviously won't work for pre-built slave devices, although many have a reset pin which can reset the whole chip if you're in a situation where the time for a slave to restart doing its job after a reset isn't too long and where it doesn't have anything in volatile memory you'd need to keep.

author: fourfathom
author_rank: Super Contributor
timestamp: July 01, 2023, 01:02:15 am
content: Here's a follow-up on the I2C mux (and also my SAMD clocking question elsewhere):I used the "analog mux on the I2C data line" trick, with a timer-tick ISR to manage the selection of the I2C device (this is in a six-channel ham radio beacon, each channel gets a timeslot and the necessary I2C activity takes much less than the timeslot duration.) Here's a link to the beacon project announcement:https://turnislandsystems.com/meet-the-beaconblaster-6/I've got a couple of prototypes running now.Thank you all for your advice!

author: Siwastaja
author_rank: Super Contributor
timestamp: July 01, 2023, 06:55:00 am
content: I had a design where I needed to switch 10-to-1* 8-bit syncronous parallel bus + clock signal (50-MHz-ish)* I2C* one analog signal (phototransistor-generated voltage)These were special time-of-flight imager chips, interfaced to STM32F743 MCU.I did it with four 12-bit 1-to-3 analog switches, SN74CBT16214C. The only special need really was to place I2C pull-ups at the slave side so that each of the ten had their own. Of course this mux tree needed 8 GPIO signals in total to choose the active slave, but number of IO is not always a problem.All those signals ran in 50-pin 0.5mm pitch flat-flex cables, with every other line as ground for modest level of shielding and impedance control. Never saw any problems with I2C or parallel bus either.

author: VK3DRB
author_rank: Super Contributor
timestamp: July 01, 2023, 07:58:51 am
content: Quote from: nctnico on May 26, 2023, 06:59:38 pmMore like around 4.7K pullup, depending upon load capacitance and data speed. Best to check the waveform on an oscilloscope and use resistors according to the waveform so it meets the I2C standard, and/or that provided by the datasheets. I have done designs with six devices on the one bus and had to use 2.2K pullups.

author: Siwastaja
author_rank: Super Contributor
timestamp: July 01, 2023, 08:41:55 am
content: Maybe nctnico meant these 100k pull-ups as extras, only to maintain idle states, in addition to to the "main" pullups (maybe 2.2k) somewhere else (e.g. at the master); that would work. Although I fail to see the advantage in this as you need two more resistors in total.

author: fourfathom
author_rank: Super Contributor
timestamp: July 01, 2023, 03:40:12 pm
content: I used a strong pull-up on the controller side of the analog mux, and two weak pull-ups at the mux pins that feed the devices. I guess two strong pull-ups on the device side would have been just fine, but I didn't want to risk having the controller side left floating during mux switching transitions. No doubt the bus capacitance would have been adequate to hold the levels, but I decided on "an abundance of caution". And it's just one practically free resistor.

author: nctnico
author_rank: Super Contributor
timestamp: July 01, 2023, 06:21:05 pm
content: Quote from: Siwastaja on July 01, 2023, 08:41:55 amThe 100k Ohm is to maintain idle state indeed. IMHO you'll need those as I2C pins on I2C peripherals chips typically don't have pull-ups and will float. An open pin can easely pick up enough from the pin next to it to make it see a different logic level.

author: Siwastaja
author_rank: Super Contributor
timestamp: July 01, 2023, 06:39:24 pm
content: Probably simplest and most robust solution would be 1:1 distributed between the two sides (at master, at the slave), so that if you desire 2.2kOhm, you would use 4.7kOhm on both sides for 1 BOM line and 2.35kOhm effective. In practice 2.2kOhms at master and 100kOhms at slave of course works equally well.