diff --git a/common/pimoroni_i2c.cpp b/common/pimoroni_i2c.cpp index 52fcda61..16a61aea 100644 --- a/common/pimoroni_i2c.cpp +++ b/common/pimoroni_i2c.cpp @@ -3,14 +3,28 @@ namespace pimoroni { void I2C::init() { - i2c = ((sda / 2) & 0b1) ? i2c1 : i2c0; + i2c = pin_to_inst(sda); + // TODO call pin_to_inst on sda and scl, and verify they are a valid i2c pin pair + // TODO maybe also fall back to PIO i2c for non-standard pin combinations + + // Since it's easy to leave the I2C in a bad state when experimenting in the MicroPython REPL + // this loop will find any I2C pins relevant to the current instance and reset them. + for(auto pin = 0u; pin < 30; pin++) { + if(pin_to_inst(pin) == i2c && gpio_get_function(pin) == GPIO_FUNC_I2C) { + gpio_disable_pulls(pin); + gpio_set_function(pin, GPIO_FUNC_NULL); + } + } i2c_init(i2c, baudrate); - gpio_set_function(sda, GPIO_FUNC_I2C); gpio_pull_up(sda); gpio_set_function(scl, GPIO_FUNC_I2C); gpio_pull_up(scl); } + i2c_inst_t* I2C::pin_to_inst(uint pin) { + return ((pin >> 1) & 0b1) ? i2c1 : i2c0; + } + /* Basic wrappers for devices using i2c functions directly */ int I2C::write_blocking(uint8_t addr, const uint8_t *src, size_t len, bool nostop) { return i2c_write_blocking(i2c, addr, src, len, nostop); diff --git a/common/pimoroni_i2c.hpp b/common/pimoroni_i2c.hpp index 87146c8e..5066022a 100644 --- a/common/pimoroni_i2c.hpp +++ b/common/pimoroni_i2c.hpp @@ -47,6 +47,8 @@ namespace pimoroni { gpio_set_function(scl, GPIO_FUNC_NULL); } + i2c_inst_t* pin_to_inst(uint pin); + void reg_write_uint8(uint8_t address, uint8_t reg, uint8_t value); uint8_t reg_read_uint8(uint8_t address, uint8_t reg); uint16_t reg_read_uint16(uint8_t address, uint8_t reg);