I2C Traffic control - Page 1
Forum section: electronics / projects

author: oliv3r
author_rank: Frequent Contributor
timestamp: November 24, 2023, 09:30:08 am
content: Hey all,I have a device, containing an STM32 microcontroller, which acts as an 400kHz I2C master, en controls an I2C multichannel LED driver, but also has a I2C light sensor. No interrupt lines.I now want to 'hijack' the I2C bus with an ESP32, but a) want the I2C bus to function as normally when the ESP32 'not available (powered off, sleeping who knows). But if the ESP32 is ready, it would like to be the I2C master. I do not want this to be a multi-master bus, as I don't want both devices controlling the leds. The ESP32 should get the led settings (to translate it internally to a LED state if you will), and then make its own choices on what leds to show.So I've came up with this, but no idea if this can and will work at allIs this even possible.Logically it looks sane, but I2C is open-drain, so will this work, and if not, what is possible here at all?SDA_IN is the STM32 Master, going to the ESP32 slave port (IN), SDA_OUT goes to the slaves, but is also connected to the ESP32 master port (OUT).Thanks

author: tooki
author_rank: Super Contributor
timestamp: November 24, 2023, 11:00:30 am
content: So you want a multimaster bus without it being a multimaster bus?!?Multimaster simply means that you have to ensure the different masters don’t step on each other’s toes.I also think there’s maybe a misconception about how I2C reads work, in that you maybe think that reading is a fully passive process, unlike a write. But in actuality, every I2C read begins with a write that tells the slave which register you want to read.Maybe you can explain more of the actual application, i.e. your design goals, so we avoid an XY problem (Google that if you’re not familiar).

author: Siwastaja
author_rank: Super Contributor
timestamp: November 24, 2023, 12:12:16 pm
content: Sounds like the usual multi-master configuration. Read relevant documentation.

author: oliv3r
author_rank: Frequent Contributor
timestamp: November 24, 2023, 01:06:02 pm
content: I think I tried to explain quite well what I wantedBut I'll try again.A micro controller is responsible for reading and writing to and from a LED + lightsensor. Internally, the light sensor data is used (among other things) to do brightness control of the LED's. The STM32 is also responsible for controlling the LED's via the I2C led driver. All simple and logical I would say.STM32 -> LED + LightsensorOnce the ESP32 is up and running, The ESP32 now becomes the boss over the leds. The STM32 still wants to send messages to those leds, but those are not relevant. The ESP32 needs to override them.So an example is, the STM32 is up; the ESP32 is sleeping/doing something that not involves the LED's. The STM32 pulsates in a rainbow color an RGB led. Lets say for arguments sake, that's the only job of the STM32, to generate a rainbow pattern; but the current color of the rainbow, is important for the ESP32.Now, the situation changes, and the ESP32 wants to control the LED. For example, every time the Red component in the RGB pattern comes up; the ESP32 keeps the LED to red.So, the ESP32 will need to read the LED I2C messages, and every time the Red component is dominant, the ESP32 fully turns on the LED (by sending the i2c write message 255, 0, 0 the the appropriate registers.If I where to use multi-master, the ESP32 needs to either spam the RGB value constantly, overwriting what the STM32 just sent (which surely will be an ugly effect), or the led driver will only accept messages from the ESP32 master. I think neither of those are acceptable solutions.Once the ESP32 goes into sleep mode; and lets go of the bus, the STM32 is in full control of the leds again.Did this hopefully describe better what I intended? Note that the rainbow + red is just an example. The truth is, that the STM32 will control multiple leds, and will use it to indicate various states of the STM32's statemachine. Also important to note, that the STM32 is a black box, which I don't have source code for, nor do I wish to reflash it. Obviously, if I could change the content of the STM32, the solution would be far far simpler

author: PlainName
author_rank: Super Contributor
timestamp: November 24, 2023, 01:57:26 pm
content: There may be an issue with interrupting the lines mid-conversation, leaving the slaves going 'wtf?!?' and ignoring stuff.Perhaps a cleaner way would be to have the STM talk only to the ESP32, and the ESP32 translate and output for the LEDs. So two I2C busses, essentially. Of course, the ESP32 will need to be awake all the time, but I couldn't figure out if this is the normal case (and the ESP32 just doesn't get in the way but is otherwise running), or if the ESP32 is in sleep mode or something.Anyway, normally the STM would send a message to the ESP32 which would just reroute it straight out to the LEDs. If it spots something it needs to fix up it changes or otherwise deals with the message as it goes from bus1 input to bus2 output. Simples.

author: Siwastaja
author_rank: Super Contributor
timestamp: November 24, 2023, 02:07:25 pm
content: Quote from: oliv3r on November 24, 2023, 01:06:02 pmOK, this thing I missed. Indeed, if you want to silence a master which does not have a silencing feature and it cannot be added because of the blackboxiness, then I think there is no other way to what you described, physically disconnecting that black box master by using e.g. semiconductor switches. Given that I2C is open-drain and assuming the STM32 is never configured in push-pull mode, then those MOSFET switches, even with their parasitic diodes, should do the trick I guess.There can be nasty timing issues if the STM32 is silenced mid-operation; you can try to mitigate by just listening on the ESP side and then silence the master right after a transaction, knowing the characteristics of it (how long it takes to start the next one); or you can hope that the slaves cope with a transaction which is cut mid-way. At least you can use the I2C reset sequence (9 SCL pulses) on the ESP side.

author: oliv3r
author_rank: Frequent Contributor
timestamp: November 24, 2023, 02:39:59 pm
content: That was my thought too; but then I know not much about electronics design when it comes to these tricky detailsSo the ESP32 'slave' side is always connected, and I imagine power up going something like:boot, listen on I2C bus, see what's going on, find a window to interrupt the link, or; as you describe, just cut it off and send 9 clocks. The power to the led board would be going over the interceptor cable as well, so I could add a nother mosfet like this one, to switch power (default on), which would allow me to power-cycle the entire boardI just realized, that I can control the mosfets of course with a single pin, as there's zero value in switching them individually. But do I need to resistors or can I use just the one (I would think so) Any very common mosfets in dual packages that are easy to find on lcsc?

author: Peabody
author_rank: Super Contributor
timestamp: November 24, 2023, 03:31:09 pm
content: Can someone explain how the proposed mosfet circuit works, including which devices are connected to what nets? The gate of the N-channel mosfet needs to be higher than the source by at least the threshold voltage to turn it on, so how exactly does this work?

author: oliv3r
author_rank: Frequent Contributor
timestamp: November 24, 2023, 03:57:55 pm
content: That's electrical knowledge I indeed lack :pI put something basic but similar into falstad circuit simulator and it worked; but that doesn't tell us much.SDA is a 3v3 signal, so there's at least that.

author: Peabody
author_rank: Super Contributor
timestamp: November 24, 2023, 04:14:58 pm
content: But what are I2C_SDA_PASS, SDA_IN, and SDA_OUT connected to?

author: Peabody
author_rank: Super Contributor
timestamp: November 24, 2023, 07:08:16 pm
content: Ok, if SDA_IN is connected to the STM32, and SDA_OUT is connected to the slaves, then SDA_OUT will still follow SDA_IN whether the mosfet is switched on or not. That's because of the body diode. If SDA_IN goes low, then SDA_OUT will also go low. Always.There may be a way to make this work with a single mosfet switch, but I think this is why God created DPDT analog switches. Something like a MAX4525.

author: Roehrenonkel
author_rank: Frequent Contributor
timestamp: November 24, 2023, 07:42:07 pm
content: Hi oliv3r,have a look at PCA9544/9545. I²C-Bus-switch /-multiplexer.Maybe it helps.Good luck

author: ajb
author_rank: Super Contributor
timestamp: November 24, 2023, 08:55:41 pm
content: Quote from: Peabody on November 24, 2023, 03:31:09 pmit’s the same basic idea as the common mosfet-based I2C level shifter circuits you see on all kinds of hobbyist boards. Ignore the ‘_PASS’ connection for the moment so the gate is constantly pulled up to 3v3. If a device pulls ‘_OUT’ low, that takes to source of the N-channel FET to ~0V, so Vgsis now 3.3V, which turns the FET on, pulling the drain and ‘_IN’ low as well. Conversely, if a device pulls ‘_IN’ low, it also pulls ‘_OUT’ low via the FET’s body diode. If the gate is pulled low via the ‘_PASS’ connection, then the gate is always at or below the source voltage, and the FET never turns on. But the body diode will still allow a device on the ‘_IN’ side side to pull ‘_OUT’ low. So this won’t actually work for the OP as described, because even when ‘off’ data is only blocked in one direction. That can be solved by replacing the single FETs with a back-to-back pair, with their sources and gates connected together.

author: Peabody
author_rank: Super Contributor
timestamp: November 24, 2023, 10:25:58 pm
content: Quote from: ajb on November 24, 2023, 08:55:41 pmYes, I think that's right. But if there's a chance the ESP32 will be connected, but powered down, then he would also need to add a logic inverter in the gate line so the ESP32 would have to generate high voltage to bring the gate line low.Would you connect the sources together or the drains together? Well, it may not matter. Anyway, the 8205 dual N-channel mosfets chip would work, one each for SDA and SCL.Edit: I guess I still like the analog switch. Even the lowly CD4053 would probably work.

author: nctnico
author_rank: Super Contributor
timestamp: November 24, 2023, 10:48:06 pm
content: Why not use the ESP32 to control everything? The modern ones have oodles of processing power and flash and likely outperforms the STM32 by miles.

author: oliv3r
author_rank: Frequent Contributor
timestamp: November 25, 2023, 03:00:10 pm
content: Quote from: Peabody on November 24, 2023, 04:14:58 pmI2C_SDA_PASS is connected to the ESP32 via a GPIO, which will pull the pin low (there default pull-up is to keep it on/conducting).SDA_IN is the I2C SDA output from the STM32, SDA_OUT, is both the salves, and also the I2C output of the ESP32.Quote from: Peabody on November 24, 2023, 07:08:16 pmThat's a bit sadI took this desgin from a power switch, where there was 3v3 mosfet 3v3, and the gate was used to switch the power on/off. So I figured, I2C should work more or less the same, as I can see two scenario's happen.the gate is high, the output of the mosfet is whatever is on the input. E.g. data high, mosfet high, data low, mosfet low.If the gate is low, the mosfet is turned off, and no matter what happens on the input of the mosfet, it won't go 'through' the mosfet. e.g. a switch.As for a DPDT digital switch, I think that's a great suggestion!Quote from: Roehrenonkel on November 24, 2023, 07:42:07 pmI think that'll do the opposite, going from a single I2C master, to multiple busses, if it would do the opposite, that would be usefull.Quote from: ajb on November 24, 2023, 08:55:41 pmAh, see that's useful information and kind of makes sense. Back-to-back pair, would double the part count, and a DTDS chip is then probably more useful.Quote from: nctnico on November 24, 2023, 10:48:06 pmWould love to! But the STM32 obviously does a lot morethere's a uart connection between the esp32 and the STM32 for the other control messages. But as the STM32 is a black box, and currently in control of the LED's, which is what I actually don't want.

author: Peabody
author_rank: Super Contributor
timestamp: November 25, 2023, 04:14:19 pm
content: I've never actually tried it, but it seems to me that this chip:https://www.digikey.com/en/products/detail/texas-instruments/TS5A23159DGSR/862569should work. It's two SPDT analog switches, with very low resistance. Maybe there's a better choice, but this one is $.76 at Digikey, and is in stock.The NC pins would be connected to the STM32 I2C lines, the NO pins to the ESP32 I2C lines, and a pulldown resistor on the digital control pins, which would be connected together to an ESP32 GPIO pin. So the default would have the STM32 connected, and the changeover could occur only if the ESP32 is present and powered up, and elects to take over.

author: oliv3r
author_rank: Frequent Contributor
timestamp: December 04, 2023, 02:32:54 am
content: Looking a bit around on lcsc, found an even cheaper one, sadly not in stockhttps://www.lcsc.com/product-detail/Analog-Switches-Multiplexers_onsemi-NLAS5213AMUTAG_C3657354.htmlbut at 20 cents quantity of 1 (8 cents when buying 200+), these parts are cheap. and Ron is 1.3Ohm, perfectnow gotta find parts that are on stock.Looks likehttps://www.lcsc.com/product-detail/Others_RUNIC-RS2227XN_C255478.htmlis the next best up, though it's a DPDT, but a lot cheaper thenhttps://www.lcsc.com/product-detail/Analog-Switches-Multiplexers_onsemi-FSUSB31K8X_C184088.html...