2026-02-13 12:09 PM - last edited on 2026-02-18 12:38 AM by mƎALLEm
Hello everyone.
I am trying to build an i2c multi-drop network with STM32C0316CT6 targets. To achieve that i use the differential buffer PCA9615. Each target (and the master of course) has its own PCA9615, the topology is as shown in the picture below.
My problem is that when clock stretch is enabled (default) and master pulls the clock low, then the target pulls the clock also low for a tiny amount of time during the normal pulse duration. PCA9615 i2c a-side (non-differential) sets the SCL (a-side) low to ~0.3V (as expected) and then the target pulls the SCL to 0V for that tiny amount of time. For that tiny amount of time, the master and the target are both holding the clock low. That results in an extra voltage offset on the differential side of the buffer.
On the multi-drop network, all targets do the same and the differential voltage offset is multiplied and gets huge. The expected behaviour would be from the target to pull the line low only in the stretched pulse and not on every single pulse.
This phenomenon happens only when clock stretch is enabled, independently of clock speed or any other i2c settings.
Increasing the I2C Speed Mode parameter shortens the extra low pulse duration (actual i2c speed same).
Increasing the Digital Filter, the pulse appears a few ns later.
Analog Filter makes no difference.
Changing Rise and Fall time affect the extra low pulse duration.
I am using 2.21K external pull-ups.
In the following images blue is the differential SCL pulse and yellow the a-side (MCU side) SCL pulse. In one image the differential pulse is multiplied.
PLEASE help me understand why this extra low pulse appears and how to get rid of it.
2026-02-13 2:41 PM
Are you having trouble with the bus (i.e. unable to talk to devices), or are you just looking at the signals?
You can't look at only one of the differential pair of signals and know what the differential bus is doing.
If this multi-drop network spans multiple boards, how good are your ground connections between the boards?
2026-02-14 8:13 AM - edited 2026-02-14 8:14 AM
I think that is the expected behavior in case of an I2C device with enabled Bus streching, the device will hold the Clock signal low until it has put a valid data on the Data line. So increasing the clock of the I2C block will reduce this time, but it will never go away.
On a "normal" I2C Bus this is not visible, but Your differential bus will show this.
Why are you thinking that this is a problem? The only problem maybe that this generates EMC disturbance, if this is the case you need to use better cables (shielded), or reduce the Port speed to a lower value.
2026-02-16 6:14 AM
Thank you for your responses.
I do have problem on the bus and I am trying hardly to understand what is happening on that bus. The bus communication depends on the software and the i2c parameters.
Differential signals are perfectly mirrored one the scope and perfectly squared when clock stretch is disabled. I use Ethernet cables, where one twisted pair is for SCL+/-, one for SDA+/-, one for 24V/GND and one for 5V(PCA9615 VDDb)/GND. Every device has 2 Ethernet ports in parallel and PCA9615 is super close to them.
Stretching extends LOW duration, my LOW duration is not affected by the phenomenon. Only voltage depth changes and only for a few ns as shown in Image4.
I managed to run a test code on 18 targets (I have no more now) with clock stretch enabled without any problem.In my original code after the 10th, targets stop to ACK randomly. So code does matter, as also the i2c parameters. With i2c speed mode parameter set to "Standard Mode" or "Fast Mode" instead of "Fast Mode Plus"(even if not used), I am limited to 6 targets. The behaviour is exactly the same independ of the actual bus speed. 100kHz and 400kHz same results. I believe that because of the shorter "extra low pulse" duration created when "Fast Mode Plus" is selected, the phenomenon is lighter and more targets can work.
I noticed on the scope that when targets stop to ACK (over the target limit), the clock pulse in not transferred from the differential side to MCU side (a-side) of that board (check the picture below). I also noticed that the phenomenon is much more intense on the address bytes, as in the picture below. That explains why the target does not ACK on its address. I do not get corrupted packets when i get them, just the target never responds.
Even if I manage to optimize the code and run more targets, the bus is not healthy and can cause troubles in the future. I am using the network on remote industrial environments and I use I2C also for firmware updates. As a workaround, I use now differential lines in parallel. 24 devices have been used with 4 differential lines in parallel (limit 6 per differential channel).
It is important for me to understand why is this "extra low pulse" is generated when clock stretch is enabled and how to fix it. If you see on image4 of the original post, the differential SCL (blue) pulls the MCU SCL (yellow) LOW, but for some reason, logical or electrical, the MCU pulls the SCL LOW again and the differential SCL follows creating the trouble.
Any help is much appreciated.
2026-02-16 6:42 AM
I'm very suprised by the difference in voltage between "normal Clock LOW" and "forced Clock LOW".
Could it be that You have the terminator resistors on all nodes? This resistors have to be only on the first and the last node, for examples as terminator plug's on the line.
By the way, why are You using IIC (Inter-Integrated-Circuit) in this mode? I would use CAN-Bus or RS485/RS422.
2026-02-17 6:43 AM
Yes, termination resistors only on first and last node with the manual recommend values .
The low voltage offset is expected. PCA9615s manual says "To prevent bus latch-up, the I2C-bus/SMBus side employs static offset." It is also shown on figure 12 of the manual.
I understand that CAN and RS485 are the industrial standards. I2C is more familiar to me, is natively supported by all microcomputers, all microprocessors, and most digital sensors. Adding a new sensor to the network is super easy, without extra MCU (Hardware + Software). Firmware update (important to me) over I2C was easy to test and implement without extra hardware. Bus speed must not be predefined and can be easily adjusted based on the network needs. I tested a relay controller in 100 meter distance with Ethernet cable for power and data (100kHz) and even with the expected voltage drop, the device was working without any issue. I believe this buffer is a good device.
2026-02-17 7:33 AM
There's not only cable length and capacitance, each device adds its input capacitance.
Maybe that's getting too much for the drivers?
From the datasheet, @ 1 MHz:
• Differential I2C-bus on cable side supporting multi-drop bus
– Maximum cable length: 3 m (approximately 10 feet) (longer at lower frequency)
2026-02-17 8:56 AM
I never tried 1MHz, but 3 meters is a very pessimistic estimation in my opinion. Sparkfun and other users report up to 100 feet (unknown speed). In a test I installed a node at 50 meters and a second at 100 meters. Both working at 100 kHz the same time without issues.
In my test setup, I have now 18 nodes on my desk very close to each other. Depending on the software, they run with clock stretch without problem, even with that crazy spike.
I am trying to understand why the MCU sinks SCL to LOW on every pulse for that tiny amount of time. Can it be something electrical on the pin? A pin configuration when clock stretch is enabled? Something logical on the library?
That extra low pulse appears only when clock stretch is enabled.
2026-02-17 10:18 AM
As I already sayed I think this is how the PCA9615, and the I2C controller in the STM32 works, you may not be able to change this.
As You noticed the PCA9615 is stopping to forward the clock to the "normal" I2C Bus, so this is a problem of the PCA9615, probably better to ask NXP. I don't think that this drivers are designed for what you are using them for (Bus length and number of nodes).
2026-02-21 2:23 AM
For people who come across with the same issue, reference manual (RM0490) reports:
"At every clock pulse, after SCL falling edge detection, I2C operating as controller or target stretches SCL low during at least [(SDADEL + SCLDEL + 1) x (PRESC + 1) + 1] x tI2CCLK, in both transmission and reception modes."(p. 684)
"After SCL falling edge detection.The stretch is released after [(SDADEL + SCLDEL + 1) x (PRESC+ 1) + 1] x tI2CCLK period." (p.689)
I don't like the fact that there is no option to disable stretch on every single pulse (when clock stretch is enabled), but this is how it works.