Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ports/atmel-samd/common-hal/busio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Sercom *samd_i2c_get_sercom(const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda,
}

void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, bool internal_pullup, uint32_t frequency, uint32_t timeout) {
uint8_t sercom_index;
uint32_t sda_pinmux, scl_pinmux;

Expand Down
2 changes: 1 addition & 1 deletion ports/broadcom/common-hal/busio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ void reset_i2c(void) {
}

void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, bool internal_pullup, uint32_t frequency, uint32_t timeout) {
size_t instance_index = NUM_I2C;
uint8_t scl_alt = 0;
uint8_t sda_alt = 0;
Expand Down
2 changes: 1 addition & 1 deletion ports/cxd56/common-hal/busio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#include "shared-bindings/busio/I2C.h"

void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl,
const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
const mcu_pin_obj_t *sda, bool internal_pullup, uint32_t frequency, uint32_t timeout) {
if (frequency != I2C_SPEED_STANDARD && frequency != I2C_SPEED_FAST) {
mp_raise_ValueError(translate("Unsupported baudrate"));
}
Expand Down
2 changes: 1 addition & 1 deletion ports/espressif/common-hal/busio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#include "supervisor/shared/translate.h"

void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, bool internal_pullup, uint32_t frequency, uint32_t timeout) {
// Pins 45 and 46 are "strapping" pins that impact start up behavior. They usually need to
// be pulled-down so pulling them up for I2C is a bad idea. To make this hard, we don't
// support I2C on these pins.
Expand Down
2 changes: 1 addition & 1 deletion ports/mimxrt10xx/common-hal/busio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ static void i2c_check_pin_config(const mcu_pin_obj_t *pin, uint32_t pull) {
}

void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, bool internal_pullup, uint32_t frequency, uint32_t timeout) {

#if CIRCUITPY_REQUIRE_I2C_PULLUPS
// Test that the pins are in a high state. (Hopefully indicating they are pulled up.)
Expand Down
13 changes: 11 additions & 2 deletions ports/nrf/common-hal/busio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,13 @@ static uint8_t twi_error_to_mp(const nrfx_err_t err) {
return 0;
}

void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, bool internal_pullup, uint32_t frequency, uint32_t timeout) {
if (scl->number == sda->number) {
mp_raise_ValueError(translate("Invalid pins"));
}



// Find a free instance.
self->twim_peripheral = NULL;
for (size_t i = 0; i < MP_ARRAY_SIZE(twim_peripherals); i++) {
Expand Down Expand Up @@ -126,7 +128,14 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *
// We must pull up within 3us to achieve 400khz.
common_hal_mcu_delay_us(3);

if (!nrf_gpio_pin_read(sda->number) || !nrf_gpio_pin_read(scl->number)) {
// Set pulls up if internal_pullup is true
if (internal_pullup){
nrf_gpio_pin_pull_t hal_pull = NRF_GPIO_PIN_PULLUP;

nrf_gpio_cfg_input(scl->number, hal_pull);
nrf_gpio_cfg_input(sda->number, hal_pull);
}
else if (!nrf_gpio_pin_read(sda->number) || !nrf_gpio_pin_read(scl->number)) {
reset_pin_number(sda->number);
reset_pin_number(scl->number);
mp_raise_RuntimeError(translate("No pull up found on SDA or SCL; check your wiring"));
Expand Down
1 change: 1 addition & 0 deletions ports/nrf/mpconfigport.mk
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ ifeq ($(MCU_CHIP),nrf52833)
MCU_SERIES = m4
MCU_VARIANT = nrf52
MCU_SUB_VARIANT = nrf52833
CIRCUITPY_INTERNAL_PULLUPS = 1

SD ?= s140
SOFTDEV_VERSION ?= 7.0.1
Expand Down
13 changes: 10 additions & 3 deletions ports/raspberrypi/common-hal/busio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void reset_i2c(void) {
}

void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, bool internal_pullup, uint32_t frequency, uint32_t timeout) {
self->peripheral = NULL;
// I2C pins have a regular pattern. SCL is always odd and SDA is even. They match up in pairs
// so we can divide by two to get the instance. This pattern repeats.
Expand Down Expand Up @@ -92,7 +92,14 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
// We must pull up within 3us to achieve 400khz.
common_hal_mcu_delay_us(3);

if (!gpio_get(sda->number) || !gpio_get(scl->number)) {
// Set pulls up if internal_pullup is true
if (internal_pullup){
nrf_gpio_pin_pull_t hal_pull = NRF_GPIO_PIN_PULLUP;

nrf_gpio_cfg_input(scl->number, hal_pull);
nrf_gpio_cfg_input(sda->number, hal_pull);
}
else if (!nrf_gpio_pin_read(sda->number) || !nrf_gpio_pin_read(scl->number)) {
reset_pin_number(sda->number);
reset_pin_number(scl->number);
mp_raise_RuntimeError(translate("No pull up found on SDA or SCL; check your wiring"));
Expand All @@ -112,7 +119,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
//
// Do not use the default supplied clock stretching timeout here.
// It is too short for some devices. Use the busio timeout instead.
shared_module_bitbangio_i2c_construct(&self->bitbangio_i2c, scl, sda,
shared_module_bitbangio_i2c_construct(&self->bitbangio_i2c, scl, sda, internal_pullup,
frequency, BUS_TIMEOUT_US);

self->baudrate = i2c_init(self->peripheral, frequency);
Expand Down
2 changes: 1 addition & 1 deletion ports/stm/common-hal/busio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void i2c_reset(void) {
}

void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, bool internal_pullup, uint32_t frequency, uint32_t timeout) {

// Match pins to I2C objects
I2C_TypeDef *I2Cx;
Expand Down
7 changes: 7 additions & 0 deletions py/circuitpy_mpconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,13 @@ typedef long mp_off_t;
#define BOARD_UART_ROOT_POINTER
#endif

// Support for internal pullups for boards that have them: e.g. nrf52833
#if CIRCUITPY_INTERNAL_PULLUPS
#define HAS_INTERNAL_PULLUPS = true
#else
#define HAS_INTERNAL_PULLUPS = false
#endif

#if CIRCUITPY_DISPLAYIO
#ifndef CIRCUITPY_DISPLAY_LIMIT
#define CIRCUITPY_DISPLAY_LIMIT (1)
Expand Down
4 changes: 4 additions & 0 deletions py/circuitpy_mpconfig.mk
Original file line number Diff line number Diff line change
Expand Up @@ -462,3 +462,7 @@ CFLAGS += -DCIRCUITPY_WATCHDOG=$(CIRCUITPY_WATCHDOG)

CIRCUITPY_WIFI ?= 0
CFLAGS += -DCIRCUITPY_WIFI=$(CIRCUITPY_WIFI)

# support for internal pullups
CIRCUITPY_INTERNAL_PULLUPS ?= 0
CFLAGS += -DCIRCUITPY_INTERNAL_PULLUPS=$(CIRCUITPY_INTERNAL_PULLUPS)
4 changes: 3 additions & 1 deletion shared-bindings/bitbangio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
//|
//| :param ~microcontroller.Pin scl: The clock pin
//| :param ~microcontroller.Pin sda: The data pin
//| :param bool internal_pullups: Set pulls on each pin to up if board supports internal pullups - defaults to false
//| :param int frequency: The clock frequency of the bus
//| :param int timeout: The maximum clock stretching timeout in microseconds"""
//| ...
Expand All @@ -64,6 +65,7 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args,
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_internal_pullup, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
{ MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} },
};
Expand All @@ -75,7 +77,7 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args,

bitbangio_i2c_obj_t *self = m_new_obj(bitbangio_i2c_obj_t);
self->base.type = &bitbangio_i2c_type;
shared_module_bitbangio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int);
shared_module_bitbangio_i2c_construct(self, scl, sda, args[ARG_internal_pullup].u_int, args[ARG_frequency].u_int, args[ARG_timeout].u_int);
return (mp_obj_t)self;
}

Expand Down
1 change: 1 addition & 0 deletions shared-bindings/bitbangio/I2C.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ extern const mp_obj_type_t bitbangio_i2c_type;
extern void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self,
const mcu_pin_obj_t *scl,
const mcu_pin_obj_t *sda,
bool internal_pullup,
uint32_t frequency,
uint32_t us_timeout);

Expand Down
6 changes: 4 additions & 2 deletions shared-bindings/busio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
//|
//| :param ~microcontroller.Pin scl: The clock pin
//| :param ~microcontroller.Pin sda: The data pin
//| :param bool internal_pullups: Set pulls on each pin to up if board supports internal pullups - defaults to false
//| :param int frequency: The clock frequency in Hertz
//| :param int timeout: The maximum clock stretching timeut - (used only for
//| :class:`bitbangio.I2C`; ignored for :class:`busio.I2C`)
Expand All @@ -67,10 +68,11 @@
STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t);
self->base.type = &busio_i2c_type;
enum { ARG_scl, ARG_sda, ARG_frequency, ARG_timeout };
enum { ARG_scl, ARG_sda, ARG_internal_pullup, ARG_frequency, ARG_timeout };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_internal_pullup, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
{ MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} },
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} },
};
Expand All @@ -80,7 +82,7 @@ STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz
const mcu_pin_obj_t *scl = validate_obj_is_free_pin(args[ARG_scl].u_obj);
const mcu_pin_obj_t *sda = validate_obj_is_free_pin(args[ARG_sda].u_obj);

common_hal_busio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int);
common_hal_busio_i2c_construct(self, scl, sda, args[ARG_internal_pullup].u_int, args[ARG_frequency].u_int, args[ARG_timeout].u_int);
return (mp_obj_t)self;
}

Expand Down
1 change: 1 addition & 0 deletions shared-bindings/busio/I2C.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ extern const mp_obj_type_t busio_i2c_type;
extern void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
const mcu_pin_obj_t *scl,
const mcu_pin_obj_t *sda,
bool internal_pullup,
uint32_t frequency,
uint32_t timeout);

Expand Down
1 change: 1 addition & 0 deletions shared-module/bitbangio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ STATIC bool read_byte(bitbangio_i2c_obj_t *self, uint8_t *val, bool ack) {
void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self,
const mcu_pin_obj_t *scl,
const mcu_pin_obj_t *sda,
bool internal_pullup,
uint32_t frequency,
uint32_t us_timeout) {

Expand Down
2 changes: 1 addition & 1 deletion shared-module/board/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ mp_obj_t common_hal_board_create_i2c(void) {
busio_i2c_obj_t *self = &i2c_obj;
self->base.type = &busio_i2c_type;

common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 100000, 255);
common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, HAS_INTERNAL_PULLUPS, 100000, 255);
i2c_singleton = (mp_obj_t)self;
return i2c_singleton;
}
Expand Down
2 changes: 1 addition & 1 deletion shared-module/busio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include "py/nlr.h"

void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t freq, uint32_t timeout) {
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, bool internal_pullup, uint32_t freq, uint32_t timeout) {
shared_module_bitbangio_i2c_construct(&self->bitbang, scl, sda, freq, timeout);
}

Expand Down