I2C-in-I2C tunneling
helge wrote 07/06/2018 at 09:35 • 0 pointsI've been looking for I2C multiplexers but all I seem to find are TCA9544 and the likes which are basically analog switches / level translators merged with an 8 bit GPIO expander. Since these parts insist on receiving a stop condition after selecting downstream slave ports, devices on both sides are afterwards equally connected to SCL / SDA lines, sharing the same address space.
What I'm looking for is a device that does the opposite: accept an I2C frame with 7bit device address, 8 bit configuration, then a repeated start condition which locks the device for this transaction and gets passed through as the first start condition to the downstream slaves.
If I'm not mistaken this would be perfectly sane in terms of I2C protocol and allow tunneling of I2C transactions.
As it stands now, the simple devices on the market just act as interconnects and slaves must use their own address selection bits to achieve a unique position in the chain, limiting the number to 4 or 8 devices at most.
Is it just me or was I2C never intended to be easily reconfigurable? :D
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
You might be better just making a sequentially clocked switch. Each time you clock the select pin, it connects the next sequential I2C bus. While this seems slow, in fact you can actually select 1 of 100 buses faster than using I2C switches - and without any address conflicts or bus fault or deadlock issues. If you are sequentially reading sensors, then it is ideal. It is also self-organising, as the buses intrinsically have a positional address, without setting address jumpers.
You can use a pca9306 , pair of fets, or cmos transmission gates to switch/level shift the bus, and simple logic to shift the control signal, eg shift register, flip-flops, 74HC4017, counters. There are many ways to implement. You need to watch the C of all the switches for large number of buses. Eg 74HC4017+PCA9306 buffers makes a 10way switch. (and you could easily have a bus led, or power switch the bus too) Or you could make 2-bus daisy chain modules with 74HC74 and PCA9306's. Off C is only 4pf/PCA9306, so you could go out to a lot of buses.
You only need dedicate a single pin to controlling it. e.g. Long 1=reset, short 1=next bus. RC logic creates the start/reset condition.
Are you sure? yes | no
This is a reasonable approach. You could do something similar with the MAX14661. If you set it up in SPI mode, you can daisy chain as many as you want together with no address limitations. This would take three pins instead of one, but only one component for every channels.
If you do switch the bus with a mechanism other than the I2C bus itself, you need to be careful since switching the bus at the wrong time (any time a slave is holding it low) is the easiest way to lock up an I2C bus. One good thing about using an I2C multiplexer to make the change is that they will change at a consistent point in the I2C transaction.
Are you sure? yes | no
yes, I am thinking of a single master case, where there is not much problem to keep it all straight. Self-organising daisy chain modules is quite a plus for a certain kind of job.
Are you sure? yes | no
One trick to remember is that the bus-switches have a hardware reset pin. This lets you clear the lowest level of muxes quickly (or as you put it "deactivate all"). You should always be using the Reset pin, because a bus-deadlock or wiring fault will block changing the switch state, and thus become unrecoverable. In a large system, you need the hardware reset for reliability.
For your application (a big array), I2C Switch IC's are not neccessarily the best choice. They are expensive and require a lot of bus traffic. They have to be explicitly configured to have the hierarchy of addresses: it is not self-organising. What is good about them, is you can just clip them onto the I2C bus, and build a large hierarchy, and they can level shift.
Are you sure? yes | no
Now thinking about SPI-in-SPI tunneling (talk about changing the rules ^^) with pre-programmed ICE40LP384SG3, LAMXO256C-3TN100E or LCMXO2-256HC-4SG32C :D
Are you sure? yes | no
I think the I2C multiplexers will do what you want, at least some of them. I know at least some like the MAX14661 will transition after the acknowledge bit, so no stop is required. I am not sure why you care if there is a restart or stop and start. The flow would work similar to what you described:
I2C Start followed by the 7 bit address for the multiplexer, with the R/W# bit set low, then send the port select command and after the acknowledge for the last byte of the command the switch will reconfigure to the selected port. Once the port is selected you can start a new transaction with the slave address for the target and send stop when finished.
If you want to talk to the same device, just start another transaction.
If you want to talk to a different device, address the multiplexer and send the new port select command before addressing the new device.
You could even address the multiplexer and send the port select command every time if you want simpler code and have the extra bus bandwidth to spare.
This is the standard way to add more devices with the same address on an I2C bus. I'm not sure what sort of tunneling protocol would be more efficient.
This happens to be one of the drawbacks of I2C that was eliminated in the new I3C standard which includes dynamic address assignment, along with speed enhancements a bunch of other nice features. Unfortunately there are not many I3C devices available yet, so that isn't much help in this case.
Are you sure? yes | no
Thank you for the thorough comment. I seem to have left out a crucial bit of the thought process here, so as an addendum:
While working on a bit of IoT hardware the problem of easily hooking up 10s of sensors arose and I2C multiplexer boards seemed to be a logical approach. This would see several I2C expanders daisychained, possibly also using TCA9509 bus repeaters and slow data rates to deal with a few meters of total bus length (throughput is not critical here).
Now daisychained multiplexers that require a STOP to update and have the same address collide and can only be reset as a valid action.
If they would update right after configuration is sent and ignore subsequent bus activity except STOP (repeated start, address R/W and data), the next multiplexer in line could be addressed and configured in similar manner until a sensor at the end of the chain is reached and communicated with.
STOP in communication with the sensor would leave a chain of multiplexers active and responding to the same address to which a regular "deactivate all" command would be sent to cause reset.
Are you sure? yes | no
These I2C multiplexers have address pins so that you can change the address. All you need to do is choose a different address for each layer of the multiplexer. If you need to connect many sensors, use a part that can do at least 8:1 (like the MAX14661)
4x 8:1 devices in parallel can connect 32 sensors.
The MAX14661 can also be wired up as a 16:1 mux, and if you use one for SDA and a separate one for SCL (both set for the same address so they switch together) you have a 16:1 mux. If you use four of these pairs in parallel you can connect 64 sensors.
You can also cascade the devices. If you cascade 8:1 muxes behind a single 8:1 mux, you could use the other three address behind the first 8:1 device to add 24 more, for 192 sensors with the same address.
The theoretical maximum configuration based on the address limitations would be cascading the 16:1 configuration which could be done in 4 layers (one for each address) for up to 16^4 or 65,536 sensors.
Also, I think many I2C devices will respond to a repeated start, even if they were not the one addressed in the previous transaction, so eliminating the stop would not necessarily keep them from responding unless they were specifically designed for that. I think the existing mechanism will do what you need anyway.
Are you sure? yes | no
Fair comment, I did not think of the request from a production point of view but rather as a one off "hobby" point of view.
Failing the finding of a fully exposed address device, the only other thought I have is to "page" your devices. One chip to decode the addresses of the other devices. Now it's just a software problem.
Regars AlanX
Are you sure? yes | no
I2C, as the name implies, was supposed to be a simple protocol for talking to chips on the same PCB. Initially the addresses were supposed to be reserved by manufacturers of particular chips, so you would never get a collision. The ranges still correspond to different categories of chips. Of course, that only applied to the original I2C, and not to TWI or other variations on the topic, which are practically free-for-all.
Are you sure? yes | no
True, I2C being a 1980s vintage protocol it started out as something rather simple.
But you might have to admit that in light of capacitance isolation through buffers (TCA9509), HS multi-Mbit/s speeds, I2C oozing out of HDMI ports and even an offer for differential signalling (PCA9615) extending I2C to... more
Are you sure? yes | no
I don't know. Sure, you can do that. But there are other protocols that have been better designed for communication at those distances, and they have their own helper chips that you can use easily. CAN bus comes to mind, for example.
Are you sure? yes | no
if cheap MEMS sensors, ADCs and DACs had CAN interfaces this would make it a natural fit. Guess this part of the universe is just broken and I'll have to live with 8ct DIP switches to configure device addresses. Sometimes the solution is just... missing
Are you sure? yes | no
The argument in favor of I2C is that it combines seamlessly with other I2C sensors and accessories, using CAN or a differential serial interface would make it heterogenous and more expensive. Always fighting that dollar sign.
Are you sure? yes | no
Perhaps another ATMEGA328P 28 pin dual inline chip and just pretend it is configurable I2C chip. Bonus it comes with more GPIOs! You can avoid the crystal by fusing for the 8MHz internal RC oscillator. Don't need all those GPIOs? Then drop back to one of the ATTiny series.
Are you sure? yes | no
Spent some time producing ~300 boards, flashing ATMegas and having them register after self tests really gets old quickly. For a one-off thing that'll be ok (ignoring the additional work of implementing and qualifying the I2C node) but for 10s or 100s of boards I'd rather avoid it :)
Are you sure? yes | no