olikraus / u8g2

U8glib library for monochrome displays, version 2
Other
4.91k stars 1.02k forks source link

Pin mux conflict with RP2040 (Pico) earlephilhower Arduino core #2425

Open egnor opened 2 months ago

egnor commented 2 months ago

Using Earle Philhower's Arduino core for the RP2040/Pico and U8g2, if you are using I2C, and you (or something you call) calls Wire.begin() before calling the U8G2 driver's .begin(), AND you pass SDA and SCL pins to the U8G2 driver object's constructor, the I2C bus will be broken.

This is because the initialization code u8x8_gpio_and_delay_arduino calls pinMode to set every known pin (including SDA and SCL) to either OUTPUT or INPUT_PULLUP: https://github.com/olikraus/u8g2/blob/b325be786792efece0bdefa7c5df3d86db079271/cppsrc/U8x8lib.cpp#L99

In Earle Philhower's core, pinMode calls gpio_init on the pin in question, which resets the pin to plain GPIO (code here).

So that actually disables I2C on the pins in question, if it was set. The u8g2 code later calls Wire.begin(): https://github.com/olikraus/u8g2/blob/b325be786792efece0bdefa7c5df3d86db079271/cppsrc/U8x8lib.cpp#L1355

However, in Earle Philhower's core, if I2C had been previously started, Wire.begin() does nothing (code here).

... THUS, the (rather common actually) sequence of "application calls Wire.begin(), application calls u8g2 .begin(U8G2_R0, SCL, SDA), proceed..." actually breaks the entire I2C bus (as noted in https://github.com/olikraus/u8g2/issues/2289). One possible fix is to not call pinMode on SDA/SCL pins (and probably not SPI pins either?) to avoid disrupting pin muxing. Not sure if anyone was counting on that code enabling internal pull-ups to make I2C work??

olikraus commented 2 months ago

ok, so what does this mean? The solution in https://github.com/olikraus/u8g2/issues/2289 should work, right?

egnor commented 2 months ago

It means you can NOT pass SDA and SCL to the U8G2 driver constructor (on the rp2040 with the earlephilhower core) otherwise it breaks the bus. Even if they are the default or otherwise configured values.

So yes, you can work around it, but it's a confusing trap for the unwary.