Skip to content

Firmware hangup in i2c_stop() and other I2C functions #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
maxgerhardt opened this issue Jun 18, 2021 · 1 comment
Open

Firmware hangup in i2c_stop() and other I2C functions #3

maxgerhardt opened this issue Jun 18, 2021 · 1 comment
Labels
bug Something isn't working Component: I2C Regarding the I2C component needs testing Additional testing required

Comments

@maxgerhardt
Copy link
Member

maxgerhardt commented Jun 18, 2021

I observed it multiple times in a hardware configuration with a SSD1306 I2C OLED display that reflashing the firmware at specific points would cause the new firmware to hangup in the i2c_stop() function (as I observed in the debugger).

https://github.com/CommunityGD32Cores/GD32Core-New/blob/88d1cd79e196e13deaa67faeb7aea008f10157fd/libraries/Wire/src/utility/twi.c#L144-L155

This code does not have timeouts (as opposed to other I2C functions) and in case the I2C peripherhal wants to assert a STOP condition but the bus just doesn't let it be driven that way (some other device is interfering?) this hangs up forever.

This should be investigated and fixed.

@maxgerhardt maxgerhardt added bug Something isn't working needs testing Additional testing required Component: I2C Regarding the I2C component labels Jun 18, 2021
@maxgerhardt
Copy link
Member Author

maxgerhardt commented Oct 2, 2021

A timeout has been added in a72b50c and 51a22bf, further improvements in PR #45 #46

a backtrace of a lockup is also e.g.

Program received signal SIGINT, Interrupt.
0x08001948 in i2c_byte_write (obj=0x20000104 <Wire+20>, data=<optimized out>)
    at C:\Users\Max\.platformio\packages\framework-arduinogd32\libraries\Wire\src\utility\twi.c:157
157         while(((i2c_flag_get(obj_s->i2c, I2C_FLAG_TBE)) == RESET) &&
(gdb) where
#0  0x08001948 in i2c_byte_write (obj=0x20000104 <Wire+20>,
    data=<optimized out>)
    at C:\Users\Max\.platformio\packages\framework-arduinogd32\libraries\Wire\src\utility\twi.c:157
#1  i2c_master_transmit (obj=obj@entry=0x20000104 <Wire+20>,
    address=<optimized out>, data=0x2000014c <TwoWire::_tx_buffer> "",
    length=<optimized out>, stop=1 '<error reading variable>)
    at C:\Users\Max\.platformio\packages\framework-arduinogd32\libraries\Wire\src\utility\twi.c:241
#2  0x08001648 in TwoWire::endTransmission (this=0x200000f0 <Wire>,
    sendStop=sendStop@entry=1 '<error reading variable>)
    at C:\Users\Max\.platformio\packages\framework-arduinogd32\libraries\Wire\src\Wire.cpp:191
#3  0x08001666 in TwoWire::endTransmission (this=<optimized out>)
    at C:\Users\Max\.platformio\packages\framework-arduinogd32\libraries\Wire\src\Wire.cpp:207
#4  0x08002dfe in Adafruit_SSD1306::ssd1306_commandList (
    this=this@entry=0x20000084 <display>, c=<optimized out>,
    c@entry=0x8006f3a <Adafruit_SSD1306::begin(unsigned char, unsigned char, bool, bool)::init1> <error reading variable>, n=<optimized out>,
    n@entry=4 '<error reading variable>)
    at .pio\libdeps\genericGD32F303CC\Adafruit SSD1306\Adafruit_SSD1306.cpp:402
#5  0x08002f98 in Adafruit_SSD1306::begin (
    this=this@entry=0x20000084 <display>,
    vcs=vcs@entry=2 '<error reading variable>,
    addr=addr@entry=60 '<error reading variable>, reset=reset@entry=true,
    periphBegin=periphBegin@entry=true)
    at .pio\libdeps\genericGD32F303CC\Adafruit SSD1306\Adafruit_SSD1306.cpp:537
#6  0x08001402 in setup () at src\main.cpp:82
#7  0x08004cd6 in main ()
    at C:\Users\Max\.platformio\packages\framework-arduinogd32\cores\arduino\main.cpp:51

So really the lockup can happen at any time.

The Wire library needs an overhaul regarding error / timeout checking and I2C bus resetting.

I can reproduce most lock-ups very determinstically when I flash the I2C OLED benchmark demo and reflash it in the middle of when it's writing to the screen.

@maxgerhardt maxgerhardt changed the title Firmware hangup in i2c_stop() Firmware hangup in i2c_stop() and other I2C functions Oct 2, 2021
obra referenced this issue in keyboardio/ArduinoCore-GD32-Keyboardio Nov 16, 2021
Add fallback definitions in cases where the Arduino core fails to def…
@robcazzaro robcazzaro mentioned this issue Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Component: I2C Regarding the I2C component needs testing Additional testing required
Projects
None yet
Development

No branches or pull requests

1 participant