Another thread about HardWire I2C freeze

Post here first, or if you can't find a relevant section!
Post Reply
profdc9
Posts: 50
Joined: Mon Jun 11, 2018 11:20 am

Another thread about HardWire I2C freeze

Post by profdc9 » Thu Mar 07, 2019 3:51 pm

Hello,

I hate to bring this up again, because I have already looked at the many forum posts on this, but I figure since the forum is going to close down soon, it could be my last chance.

In the Wire.cpp maple library there is the "process" function

Code: Select all

uint8 TwoWire::process(uint8 stop) {
    int8 res = i2c_master_xfer(sel_hard, &itc_msg, 1, 0);
    if (res == I2C_ERROR_PROTOCOL) {
        if (sel_hard->error_flags & I2C_SR1_AF) { /* NACK */
            res = (sel_hard->error_flags & I2C_SR1_ADDR ? ENACKADDR : 
                                                          ENACKTRNS);
        } else if (sel_hard->error_flags & I2C_SR1_OVR) { /* Over/Underrun */
            res = EDATA;
        } else { /* Bus or Arbitration error */
            res = EOTHER;
        }
        i2c_disable(sel_hard);
        i2c_master_enable(sel_hard, dev_flags);
    }
    return res;
}
where i2c_master_xfer is called with a zero timeout. If the i2c bus for some reason is tied up, the function goes into an infinite loop and never returns because the timeout is zero.

It would be nice to be able to have some error recovery if the i2c bus doesn't work. I realize the Arduino Wire library has the same behavior, and workarounds "WSWireLib" have been devised for the Arduino to add some sort of error recovery.

Would it be possible to add a method to the Wire class so that while the timeout=0 as a default, it could be changed? For my particular application, the device may be an inaccessible place for long periods of time, and I would prefer if the device had some autonomous recovery. I realize I could use a watchdog to reset the microcontroller, but it would be nice to have an option that does not require a reset.

Thanks,

Dan

MoDu
Posts: 114
Joined: Mon Jul 16, 2018 1:51 pm

Re: Another thread about HardWire I2C freeze

Post by MoDu » Thu Mar 07, 2019 4:51 pm

If the i2c bus for some reason is tied up, the function goes into an infinite loop and never returns because the timeout is zero.
I think I've encountered this, where a bad I2C wire would lock the whole MCU on a I2C access.

profdc9
Posts: 50
Joined: Mon Jun 11, 2018 11:20 am

Re: Another thread about HardWire I2C freeze

Post by profdc9 » Fri Mar 15, 2019 3:14 am

I figured out a workaround I would share.

The problem I discovered in my device, there are two separate +5 V supplies, one for the Bluepill, and another for the rest of the circuit. I put a Schottky diode to connect the two together so that the Bluepill would not try to power the rest of the circuit, but the Bluepill could be powered by the circuit.

The 10k pullup resistors on the I2C are powered by the external supply, not the supply on the Bluepill, so that if the Bluepill is powered up by connecting it to the USB, the rest of the circuit is off, as it should be. However, the 10k resistors do not pull the SCL and SDA lines high because these are connected to the external supply.

When HardWire tries to take control of the bus, it never can succeed because the SDA and SCL lines are low, and the software spins in an infinite loop waiting for the SDA/SCL lines to go high.

As a workaround, if you know that the Bluepill is the only bus master, you can digitalRead the SDA and SCL lines and see if they are low before you try to take control of the bus with HardWire. If they are low, then you should not try to initiate a transfer as HardWire will wait indefinitely for the devices for the I2C devices to become available. In my software I added a check so that the rest of the circuit is powered on by sampling SDA/SCL and ensuring both lines are high for 250 ms before initializing the I2C devices.

Dan

ag123
Posts: 1321
Joined: Thu Jul 21, 2016 4:24 pm

Re: Another thread about HardWire I2C freeze

Post by ag123 » Fri Mar 15, 2019 5:42 am

this is a cool workaround :)

MoDu
Posts: 114
Joined: Mon Jul 16, 2018 1:51 pm

Re: Another thread about HardWire I2C freeze

Post by MoDu » Fri Mar 15, 2019 10:34 am

profdc9 wrote:
Fri Mar 15, 2019 3:14 am
(...) ensuring both lines are high for 250 ms before initializing the I2C devices
Interesting, that can be easily be added in the driver code.

Post Reply