Configuration of I2C buses - issue of multiple start bits on IC2 in single message

strud

Well-known member
Hi All,

I have a project with a number of MCP23008 digital io expanders on both the I2C bus 1 and bus 2. This is on a Teensy 4.1, running teensyduino 1.59 and being built in Platform IO.

Curiously I am not able to set the GIO2 output on when the devices are on bus2, bus 1 is fine.

The only difference I can see after significant investigation is that on bus2 the start condition is being set at the start of every byte where as this is not occuring on I2C bus1. Even so, I am struggling to understand why only the GPIO2 cannot be driven on and off while the others are fine....and this only occurs on bus2.

I am using the default Wire library, as such I cannot see how I can change the configuration to disable/enable/control the start bit behaviour ie make bus2 the same as bus1.

Is this a limitation of this library? Should I consider using an alternative?
 

Attachments

  • I2C bus1 to 2 comparison for out2 write to MCP23008.png
    I2C bus1 to 2 comparison for out2 write to MCP23008.png
    91.5 KB · Views: 23
I have a support request in with Microchip, lets see what they say.

Missing from the initial submission, I am using the Adafruit library:


Thinking of changing over to this one as it is still being maintained.

 
I don't see extra start conditions in your plot. There is a start at the beginning (data high to low while clock is high) and a stop at the end. (Data goes low to high while clock is high. No extra starts in the middle.
 
UhClem, thanks for making me take a closer look, you are definitely correct..... and this may help me find the root cause of the issue.

Those blips in the SDA2 line are not actually a start or a stop and maybe I have something else in the system driving that line. Will look into that further.

This would make more sense than the library behaving differently on one bus compared to another.
 
something else in the system driving that line.
Not driving the line. Everything on I2C is open drain so the signal will always float high (pullup resistor) when nothing is active. That bobble should be no problem as what matters is that data is stable before the rising edge of the clock.
 
Ok good point. However the problem I have is this is the only difference I can see between the two buses and this is the bus that gio2 on the expansion chip cannot be activated. The traces look identical otherwise I believe.
 
Hi MarkT, yes that would be the most plausible if it didn't work just fine when I put it back onto I2C1.

Issue repeats for multiple boards of that type and another board design. Also with MCP23008 of different production batches/years.
 
Another data point that makes it a bit weirder I think, turning them all on in a single message ie 0xFF still results in gpio2 not being set, only on I2C2.

Reading back the port value I get 251, so bit2 is not set.

Will look more into the bit directions register setting, as it really looks like something is going wrong there ie that bit is not being defined as an output.
 
Checking that all bits are configured as outputs during initialisation by reading back register 0x00 ie IO direction register. It confirms that this has been set to 0x00 ie all bits as output. This is on I2C bus 2 which is showing the issue with bit 2.
 

Attachments

  • I2C bus2 initialisation as output_with_readback.png
    I2C bus2 initialisation as output_with_readback.png
    5.1 KB · Views: 17
Capture below shows the result of writing 255 to the port when configured as output, then immediately reading back the port value. Bit 2 does NOT get set but all others are.
 

Attachments

  • I2C2_write255_out_with_readback.png
    I2C2_write255_out_with_readback.png
    9.9 KB · Views: 10
So I've been discussing this issue with a person from Microchip and decided to look for any other transmissions on the bus that might somehow get the device into an odd state.
There was a burst of data being sent to address 0x62 (the MCP23008 is at address 0x20) for a graphics LCD library. Going through my code it turns out this was in error anyway (device was not in configuration so message should not be sent).

Removing this data burst to 0x62 prior to the configuration of the MCP23008 has fixed the issue........ WOW ie GPIO2 as output can now be turned on and off as desired.

I then added a 9x clk cycle with SDA low prior to the MCP23008 configuration and left the burst of shite to 0x62 in and the MCP23008 works fine.

C++:
Wire2.beginTransmission(0);
Wire2.write((uint8_t)0);
Wire2.endTransmission(true);

This is obviouisly an obscure problem but hopefully documenting it here helps someone else one day.
 

Attachments

  • I2C2_burst_to0x62_prior_to_config.png
    I2C2_burst_to0x62_prior_to_config.png
    10.7 KB · Views: 8
Capture of writing 255 to port with readback of 255
 

Attachments

  • I2C2_write255_out_with_readback_working.png
    I2C2_write255_out_with_readback_working.png
    6.4 KB · Views: 6
Back
Top