From 37538fc0e771ab20b21e25bca7dfd72a2fd82f16 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 26 Mar 2018 15:13:52 -0700 Subject: Fix I2C init hang when the SCL pin is pulled low. We added a check to make sure the pins are in a high state before initing the bus. This leads to a friendly error message when someone forgets to add the pull up resistors to their circuit. --- ports/atmel-samd/common-hal/busio/I2C.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c index 4ac1f340c..9fbe2101d 100644 --- a/ports/atmel-samd/common-hal/busio/I2C.c +++ b/ports/atmel-samd/common-hal/busio/I2C.c @@ -72,6 +72,19 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, mp_raise_ValueError("Invalid pins"); } + // Test that the pins are in a high state. (Hopefully indicating they are pulled up.) + gpio_set_pin_function(sda->pin, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_function(scl->pin, GPIO_PIN_FUNCTION_OFF); + gpio_set_pin_direction(sda->pin, GPIO_DIRECTION_IN); + gpio_set_pin_direction(scl->pin, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(sda->pin, GPIO_PULL_OFF); + gpio_set_pin_pull_mode(scl->pin, GPIO_PULL_OFF); + + if (!gpio_get_pin_level(sda->pin) || !gpio_get_pin_level(scl->pin)) { + mp_raise_RuntimeError("SDA or SCL need a pull up"); + } + gpio_set_pin_function(sda->pin, sda_pinmux); + gpio_set_pin_function(scl->pin, scl_pinmux); // Set up I2C clocks on sercom. samd_peripherals_sercom_clock_init(sercom, sercom_index); @@ -80,12 +93,6 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, mp_raise_OSError(MP_EIO); } - gpio_set_pin_pull_mode(sda->pin, GPIO_PULL_OFF); - gpio_set_pin_function(sda->pin, sda_pinmux); - - gpio_set_pin_pull_mode(scl->pin, GPIO_PULL_OFF); - gpio_set_pin_function(scl->pin, scl_pinmux); - // clkrate is always 0. baud_rate is in kHz. // Frequency must be set before the I2C device is enabled. -- cgit v1.2.3