Skip to content

Commit 37538fc

Browse files
committed
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.
1 parent ea39f43 commit 37538fc

File tree

1 file changed

+13
-6
lines changed
  • ports/atmel-samd/common-hal/busio

1 file changed

+13
-6
lines changed

ports/atmel-samd/common-hal/busio/I2C.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,19 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
7272
mp_raise_ValueError("Invalid pins");
7373
}
7474

75+
// Test that the pins are in a high state. (Hopefully indicating they are pulled up.)
76+
gpio_set_pin_function(sda->pin, GPIO_PIN_FUNCTION_OFF);
77+
gpio_set_pin_function(scl->pin, GPIO_PIN_FUNCTION_OFF);
78+
gpio_set_pin_direction(sda->pin, GPIO_DIRECTION_IN);
79+
gpio_set_pin_direction(scl->pin, GPIO_DIRECTION_IN);
80+
gpio_set_pin_pull_mode(sda->pin, GPIO_PULL_OFF);
81+
gpio_set_pin_pull_mode(scl->pin, GPIO_PULL_OFF);
82+
83+
if (!gpio_get_pin_level(sda->pin) || !gpio_get_pin_level(scl->pin)) {
84+
mp_raise_RuntimeError("SDA or SCL need a pull up");
85+
}
86+
gpio_set_pin_function(sda->pin, sda_pinmux);
87+
gpio_set_pin_function(scl->pin, scl_pinmux);
7588

7689
// Set up I2C clocks on sercom.
7790
samd_peripherals_sercom_clock_init(sercom, sercom_index);
@@ -80,12 +93,6 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
8093
mp_raise_OSError(MP_EIO);
8194
}
8295

83-
gpio_set_pin_pull_mode(sda->pin, GPIO_PULL_OFF);
84-
gpio_set_pin_function(sda->pin, sda_pinmux);
85-
86-
gpio_set_pin_pull_mode(scl->pin, GPIO_PULL_OFF);
87-
gpio_set_pin_function(scl->pin, scl_pinmux);
88-
8996
// clkrate is always 0. baud_rate is in kHz.
9097

9198
// Frequency must be set before the I2C device is enabled.

0 commit comments

Comments
 (0)