From 83e6e6690aeaedfe285d99bac8690e1177401fbe Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sat, 29 Jan 2022 22:44:27 -0500 Subject: [PATCH 1/3] wip; works on espressif --- locale/circuitpython.pot | 4 +- ports/espressif/common-hal/busio/I2C.c | 71 ++++++++-------- shared-bindings/busio/I2C.c | 113 ++++++++++++++----------- shared-bindings/busio/I2C.h | 11 ++- shared-module/displayio/I2CDisplay.c | 4 +- 5 files changed, 108 insertions(+), 95 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index a99a733595..3d3daf557b 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -99,7 +99,7 @@ msgstr "" msgid "%q length must be %d-%d" msgstr "" -#: shared-bindings/usb_hid/Device.c +#: shared-bindings/busio/I2C.c shared-bindings/usb_hid/Device.c msgid "%q length must be >= 1" msgstr "" @@ -631,7 +631,7 @@ msgstr "" msgid "Buffer must be a multiple of 512 bytes" msgstr "" -#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c +#: shared-bindings/bitbangio/I2C.c msgid "Buffer must be at least length 1" msgstr "" diff --git a/ports/espressif/common-hal/busio/I2C.c b/ports/espressif/common-hal/busio/I2C.c index 81b23cb3a3..349aead816 100644 --- a/ports/espressif/common-hal/busio/I2C.c +++ b/ports/espressif/common-hal/busio/I2C.c @@ -136,13 +136,19 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { self->scl_pin = NULL; } -bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { +static esp_err_t i2c_zero_length_write(busio_i2c_obj_t *self, uint8_t addr, TickType_t timeout) { + // i2c_master_write_to_device() won't do zero-length writes, so we do it by hand. i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, addr << 1, true); i2c_master_stop(cmd); - esp_err_t result = i2c_master_cmd_begin(self->i2c_num, cmd, 10); + esp_err_t result = i2c_master_cmd_begin(self->i2c_num, cmd, timeout); i2c_cmd_link_delete(cmd); + return result; +} + +bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { + esp_err_t result = i2c_zero_length_write(self, addr, 1); return result == ESP_OK; } @@ -163,45 +169,36 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, - const uint8_t *data, size_t len, bool transmit_stop_bit) { - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - i2c_master_start(cmd); - i2c_master_write_byte(cmd, addr << 1, true); - i2c_master_write(cmd, (uint8_t *)data, len, true); - if (transmit_stop_bit) { - i2c_master_stop(cmd); +static uint8_t convert_esp_err(esp_err_t result) { + switch (result) { + case ESP_OK: + return 0; + case ESP_FAIL: + return MP_ENODEV; + case ESP_ERR_TIMEOUT: + return MP_ETIMEDOUT; + default: + return MP_EIO; } - esp_err_t result = i2c_master_cmd_begin(self->i2c_num, cmd, 100 /* wait in ticks */); - i2c_cmd_link_delete(cmd); - - if (result == ESP_OK) { - return 0; - } else if (result == ESP_FAIL) { - return MP_ENODEV; - } - return MP_EIO; } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, - uint8_t *data, size_t len) { - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - i2c_master_start(cmd); - i2c_master_write_byte(cmd, addr << 1 | 1, true); // | 1 to indicate read - if (len > 1) { - i2c_master_read(cmd, data, len - 1, 0); - } - i2c_master_read_byte(cmd, data + len - 1, 1); - i2c_master_stop(cmd); - esp_err_t result = i2c_master_cmd_begin(self->i2c_num, cmd, 100 /* wait in ticks */); - i2c_cmd_link_delete(cmd); +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint8_t addr, const uint8_t *data, size_t len) { + return convert_esp_err(len == 0 + ? i2c_zero_length_write(self, addr, 100) + : i2c_master_write_to_device(self->i2c_num, addr, data, len, 100 /* wait in ticks */) + ); +} - if (result == ESP_OK) { - return 0; - } else if (result == ESP_FAIL) { - return MP_ENODEV; - } - return MP_EIO; +uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint8_t addr, uint8_t *data, size_t len) { + return convert_esp_err( + i2c_master_read_from_device(self->i2c_num, addr, data, len, 100 /* wait in ticks */)); +} + +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint8_t addr, + uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { + return convert_esp_err( + i2c_master_write_read_device(self->i2c_num, (uint8_t)addr, + out_data, out_len, in_data, in_len, 100 /* wait in ticks */)); } void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c index 19b205e4ca..a1abb4a72e 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -58,10 +58,6 @@ //| :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`) -//| -//| .. note:: On the nRF52840, only one I2C object may be created, -//| except on the Circuit Playground Bluefruit, which allows two, -//| one for the onboard accelerometer, and one for offboard use.""" //| ... //| 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) { @@ -191,23 +187,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock); //| :param int end: end of buffer slice; if not specified, use ``len(buffer)``""" //| ... //| -// Shared arg parsing for readfrom_into and writeto_then_readfrom. -STATIC void readfrom(busio_i2c_obj_t *self, mp_int_t address, mp_obj_t buffer, int32_t start, mp_int_t end) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_WRITE); - - size_t length = bufinfo.len; - normalize_buffer_bounds(&start, end, &length); - if (length == 0) { - mp_raise_ValueError(translate("Buffer must be at least length 1")); - } - - uint8_t status = common_hal_busio_i2c_read(self, address, ((uint8_t *)bufinfo.buf) + start, length); - if (status != 0) { - mp_raise_OSError(status); - } -} - STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_address, ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -219,11 +198,27 @@ STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); check_for_deinit(self); check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - readfrom(self, args[ARG_address].u_int, args[ARG_buffer].u_obj, args[ARG_start].u_int, - args[ARG_end].u_int); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); + + size_t length = bufinfo.len; + int32_t start = args[ARG_start].u_int; + const int32_t end = args[ARG_end].u_int; + normalize_buffer_bounds(&start, end, &length); + if (length == 0) { + mp_raise_ValueError_varg(translate("%q length must be >= 1"), MP_QSTR_buffer); + } + + uint8_t status = + common_hal_busio_i2c_read(self, args[ARG_address].u_int, ((uint8_t *)bufinfo.buf) + start, length); + if (status != 0) { + mp_raise_OSError(status); + } + return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 1, busio_i2c_readfrom_into); @@ -247,23 +242,6 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 1, busio_i2c_readfrom_in //| """ //| ... //| -// Shared arg parsing for writeto and writeto_then_readfrom. -STATIC void writeto(busio_i2c_obj_t *self, mp_int_t address, mp_obj_t buffer, int32_t start, mp_int_t end, bool stop) { - // get the buffer to write the data from - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_READ); - - size_t length = bufinfo.len; - normalize_buffer_bounds(&start, end, &length); - - // do the transfer - uint8_t status = common_hal_busio_i2c_write(self, address, ((uint8_t *)bufinfo.buf) + start, - length, stop); - if (status != 0) { - mp_raise_OSError(status); - } -} - STATIC mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_address, ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -278,8 +256,23 @@ STATIC mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_ma mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - writeto(self, args[ARG_address].u_int, args[ARG_buffer].u_obj, args[ARG_start].u_int, - args[ARG_end].u_int, true); + // get the buffer to write the data from + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + + size_t length = bufinfo.len; + int32_t start = args[ARG_start].u_int; + const int32_t end = args[ARG_end].u_int; + normalize_buffer_bounds(&start, end, &length); + + // do the transfer + uint8_t status = + common_hal_busio_i2c_write(self, args[ARG_address].u_int, ((uint8_t *)bufinfo.buf) + start, length); + + if (status != 0) { + mp_raise_OSError(status); + } + return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_writeto_obj, 1, busio_i2c_writeto); @@ -314,10 +307,10 @@ STATIC mp_obj_t busio_i2c_writeto_then_readfrom(size_t n_args, const mp_obj_t *p { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_out_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_in_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_out_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_out_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, - { MP_QSTR_in_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + { MP_QSTR_out_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_out_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + { MP_QSTR_in_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, }; busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); check_for_deinit(self); @@ -325,10 +318,30 @@ STATIC mp_obj_t busio_i2c_writeto_then_readfrom(size_t n_args, const mp_obj_t *p mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - writeto(self, args[ARG_address].u_int, args[ARG_out_buffer].u_obj, args[ARG_out_start].u_int, - args[ARG_out_end].u_int, false); - readfrom(self, args[ARG_address].u_int, args[ARG_in_buffer].u_obj, args[ARG_in_start].u_int, - args[ARG_in_end].u_int); + mp_buffer_info_t out_bufinfo; + mp_get_buffer_raise(args[ARG_out_buffer].u_obj, &out_bufinfo, MP_BUFFER_READ); + + size_t out_length = out_bufinfo.len; + int32_t out_start = args[ARG_out_start].u_int; + const int32_t out_end = args[ARG_out_end].u_int; + normalize_buffer_bounds(&out_start, out_end, &out_length); + + mp_buffer_info_t in_bufinfo; + mp_get_buffer_raise(args[ARG_in_buffer].u_obj, &in_bufinfo, MP_BUFFER_WRITE); + + size_t in_length = in_bufinfo.len; + int32_t in_start = args[ARG_in_start].u_int; + const int32_t in_end = args[ARG_in_end].u_int; + normalize_buffer_bounds(&in_start, in_end, &in_length); + if (in_length == 0) { + mp_raise_ValueError_varg(translate("%q length must be >= 1"), MP_QSTR_out_buffer); + } + + uint8_t status = common_hal_busio_i2c_write_read(self, args[ARG_address].u_int, + ((uint8_t *)out_bufinfo.buf) + out_start, out_length,((uint8_t *)in_bufinfo.buf) + in_start, in_length); + if (status != 0) { + mp_raise_OSError(status); + } return mp_const_none; } diff --git a/shared-bindings/busio/I2C.h b/shared-bindings/busio/I2C.h index 08701938c9..c5352fd66c 100644 --- a/shared-bindings/busio/I2C.h +++ b/shared-bindings/busio/I2C.h @@ -60,15 +60,18 @@ extern void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self); extern bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr); // Write to the device and return 0 on success or an appropriate error code from mperrno.h -extern uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, - const uint8_t *data, size_t len, - bool stop); +extern uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint8_t address, + const uint8_t *data, size_t len); // Reads memory of the i2c device picking up where it left off and return 0 on // success or an appropriate error code from mperrno.h -extern uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, +extern uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint8_t address, uint8_t *data, size_t len); +// Do a write and then a read in the same I2C transaction. +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint8_t address, + uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len); + // This is used by the supervisor to claim I2C devices indefinitely. extern void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self); diff --git a/shared-module/displayio/I2CDisplay.c b/shared-module/displayio/I2CDisplay.c index 6446e3198f..8fae5d31fd 100644 --- a/shared-module/displayio/I2CDisplay.c +++ b/shared-module/displayio/I2CDisplay.c @@ -112,12 +112,12 @@ void common_hal_displayio_i2cdisplay_send(mp_obj_t obj, display_byte_type_t data command_bytes[2 * i] = 0x80; command_bytes[2 * i + 1] = data[i]; } - common_hal_busio_i2c_write(self->bus, self->address, command_bytes, 2 * data_length, true); + common_hal_busio_i2c_write(self->bus, self->address, command_bytes, 2 * data_length); } else { uint8_t data_bytes[data_length + 1]; data_bytes[0] = 0x40; memcpy(data_bytes + 1, data, data_length); - common_hal_busio_i2c_write(self->bus, self->address, data_bytes, data_length + 1, true); + common_hal_busio_i2c_write(self->bus, self->address, data_bytes, data_length + 1); } } From cc410ad6a32d25ccd5e99502d0230999b65b8322 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 31 Jan 2022 22:03:30 -0500 Subject: [PATCH 2/3] common-hal I2C combined write_read --- locale/circuitpython.pot | 5 ++++- ports/atmel-samd/common-hal/busio/I2C.c | 17 ++++++++++++++++- ports/broadcom/common-hal/busio/I2C.c | 19 +++++++++++++++++-- ports/cxd56/common-hal/busio/I2C.c | 17 ++++++++++++++++- ports/espressif/common-hal/busio/I2C.c | 10 +++++----- ports/mimxrt10xx/common-hal/busio/I2C.c | 17 ++++++++++++++++- ports/nrf/common-hal/busio/I2C.c | 16 +++++++++++++++- ports/raspberrypi/common-hal/busio/I2C.c | 19 +++++++++++++++++-- ports/stm/common-hal/busio/I2C.c | 17 ++++++++++++++++- shared-bindings/busio/I2C.h | 6 +++--- .../i2c_device/I2CDevice.c | 2 +- shared-module/is31fl3741/IS31FL3741.c | 19 ++++++++----------- 12 files changed, 134 insertions(+), 30 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 3d3daf557b..507a6c8697 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -1616,7 +1616,7 @@ msgstr "" #: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c #, c-format -msgid "No I2C device at address: %x" +msgid "No I2C device at address: 0x%x" msgstr "" #: ports/espressif/common-hal/busio/SPI.c @@ -4069,7 +4069,10 @@ msgstr "" #: ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.h #: ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.h #: ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.h +#: ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.h +#: ports/espressif/boards/unexpectedmaker_pros3/mpconfigboard.h #: ports/espressif/boards/unexpectedmaker_tinys2/mpconfigboard.h +#: ports/espressif/boards/unexpectedmaker_tinys3/mpconfigboard.h msgid "pressing boot button at start up.\n" msgstr "" diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c index 7d77c0d43a..48ee26a9b6 100644 --- a/ports/atmel-samd/common-hal/busio/I2C.c +++ b/ports/atmel-samd/common-hal/busio/I2C.c @@ -190,7 +190,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { uint16_t attempts = ATTEMPTS; @@ -216,6 +216,11 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, return MP_EIO; } +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len) { + return _common_hal_busio_i2c_write(self, addr, data, len, true); +} + uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { @@ -242,6 +247,16 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, return MP_EIO; } +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { + uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + if (result != 0) { + return result; + } + + return common_hal_busio_i2c_read(self, addr, in_data, in_len); +} + void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { never_reset_sercom(self->i2c_desc.device.hw); diff --git a/ports/broadcom/common-hal/busio/I2C.c b/ports/broadcom/common-hal/busio/I2C.c index 8e135ab4d7..e84810cffd 100644 --- a/ports/broadcom/common-hal/busio/I2C.c +++ b/ports/broadcom/common-hal/busio/I2C.c @@ -124,7 +124,7 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { } bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { - uint8_t result = common_hal_busio_i2c_write(self, addr, NULL, 0, true); + uint8_t result = common_hal_busio_i2c_write(self, addr, NULL, 0); return result == 0; } @@ -147,7 +147,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { // Discussion of I2C implementation is here: https://github.com/raspberrypi/linux/issues/254 -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { COMPLETE_MEMORY_READS; self->peripheral->S_b.DONE = true; @@ -202,6 +202,11 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, return 0; } +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len) { + return _common_hal_busio_i2c_write(self, addr, data, len, true); +} + uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { COMPLETE_MEMORY_READS; @@ -247,6 +252,16 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, return 0; } +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { + uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + if (result != 0) { + return result; + } + + return common_hal_busio_i2c_read(self, addr, in_data, in_len); +} + void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { never_reset_i2c[self->index] = true; diff --git a/ports/cxd56/common-hal/busio/I2C.c b/ports/cxd56/common-hal/busio/I2C.c index 7b9420fa1b..82b52ca179 100644 --- a/ports/cxd56/common-hal/busio/I2C.c +++ b/ports/cxd56/common-hal/busio/I2C.c @@ -97,7 +97,7 @@ bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { return I2C_TRANSFER(self->i2c_dev, &msg, 1) < 0 ? false : true; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, const uint8_t *data, size_t len, bool stop) { +STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, const uint8_t *data, size_t len, bool stop) { struct i2c_msg_s msg; msg.frequency = self->frequency; @@ -108,6 +108,11 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, cons return -I2C_TRANSFER(self->i2c_dev, &msg, 1); } +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len) { + return _common_hal_busio_i2c_write(self, addr, data, len, true); +} + uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, uint8_t *data, size_t len) { struct i2c_msg_s msg; @@ -119,6 +124,16 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, uint8 return -I2C_TRANSFER(self->i2c_dev, &msg, 1); } +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { + uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + if (result != 0) { + return result; + } + + return common_hal_busio_i2c_read(self, addr, in_data, in_len); +} + void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { never_reset_pin_number(self->scl_pin->number); never_reset_pin_number(self->sda_pin->number); diff --git a/ports/espressif/common-hal/busio/I2C.c b/ports/espressif/common-hal/busio/I2C.c index 349aead816..454432ab91 100644 --- a/ports/espressif/common-hal/busio/I2C.c +++ b/ports/espressif/common-hal/busio/I2C.c @@ -182,19 +182,19 @@ static uint8_t convert_esp_err(esp_err_t result) { } } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint8_t addr, const uint8_t *data, size_t len) { +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return convert_esp_err(len == 0 ? i2c_zero_length_write(self, addr, 100) - : i2c_master_write_to_device(self->i2c_num, addr, data, len, 100 /* wait in ticks */) + : i2c_master_write_to_device(self->i2c_num, (uint8_t)addr, data, len, 100 /* wait in ticks */) ); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint8_t addr, uint8_t *data, size_t len) { +uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { return convert_esp_err( - i2c_master_read_from_device(self->i2c_num, addr, data, len, 100 /* wait in ticks */)); + i2c_master_read_from_device(self->i2c_num, (uint8_t)addr, data, len, 100 /* wait in ticks */)); } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint8_t addr, +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { return convert_esp_err( i2c_master_write_read_device(self->i2c_num, (uint8_t)addr, diff --git a/ports/mimxrt10xx/common-hal/busio/I2C.c b/ports/mimxrt10xx/common-hal/busio/I2C.c index 74639d0ef1..77df979e4d 100644 --- a/ports/mimxrt10xx/common-hal/busio/I2C.c +++ b/ports/mimxrt10xx/common-hal/busio/I2C.c @@ -210,7 +210,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { lpi2c_master_transfer_t xfer = { 0 }; @@ -227,6 +227,11 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, return MP_EIO; } +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len) { + return _common_hal_busio_i2c_write(self, addr, data, len, true); +} + uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { @@ -243,3 +248,13 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, return MP_EIO; } + +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { + uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + if (result != 0) { + return result; + } + + return common_hal_busio_i2c_read(self, addr, in_data, in_len); +} diff --git a/ports/nrf/common-hal/busio/I2C.c b/ports/nrf/common-hal/busio/I2C.c index de9417a6cc..322b5f2faa 100644 --- a/ports/nrf/common-hal/busio/I2C.c +++ b/ports/nrf/common-hal/busio/I2C.c @@ -238,7 +238,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) { +STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) { if (len == 0) { return common_hal_busio_i2c_probe(self, addr) ? 0 : MP_ENODEV; } @@ -266,6 +266,10 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const u return twi_error_to_mp(err); } +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { + return _common_hal_busio_i2c_write(self, addr, data, len, true); +} + uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { if (len == 0) { return 0; @@ -292,3 +296,13 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t return twi_error_to_mp(err); } + +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { + uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + if (result != 0) { + return result; + } + + return common_hal_busio_i2c_read(self, addr, in_data, in_len); +} diff --git a/ports/raspberrypi/common-hal/busio/I2C.c b/ports/raspberrypi/common-hal/busio/I2C.c index 87c78814c2..516cee2227 100644 --- a/ports/raspberrypi/common-hal/busio/I2C.c +++ b/ports/raspberrypi/common-hal/busio/I2C.c @@ -145,7 +145,7 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { } bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { - return common_hal_busio_i2c_write(self, addr, NULL, 0, true) == 0; + return common_hal_busio_i2c_write(self, addr, NULL, 0) == 0; } bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { @@ -165,7 +165,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { if (len == 0) { // The RP2040 I2C peripheral will not perform 0 byte writes. @@ -203,6 +203,11 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, } } +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len) { + return _common_hal_busio_i2c_write(self, addr, data, len, true); +} + uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { int result = i2c_read_timeout_us(self->peripheral, addr, data, len, false, BUS_TIMEOUT_US); @@ -219,6 +224,16 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, } } +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { + uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + if (result != 0) { + return result; + } + + return common_hal_busio_i2c_read(self, addr, in_data, in_len); +} + void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { never_reset_i2c[i2c_hw_index(self->peripheral)] = true; diff --git a/ports/stm/common-hal/busio/I2C.c b/ports/stm/common-hal/busio/I2C.c index ffad368a2f..5ede538b12 100644 --- a/ports/stm/common-hal/busio/I2C.c +++ b/ports/stm/common-hal/busio/I2C.c @@ -246,7 +246,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +STATIC uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { HAL_StatusTypeDef result; if (!transmit_stop_bit) { @@ -271,6 +271,11 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, return result == HAL_OK ? 0 : MP_EIO; } +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len) { + return _common_hal_busio_i2c_write(self, addr, data, len, true); +} + uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { if (!self->frame_in_prog) { @@ -288,6 +293,16 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, } } +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { + uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + if (result != 0) { + return result; + } + + return common_hal_busio_i2c_read(self, addr, in_data, in_len); +} + STATIC void i2c_clock_enable(uint8_t mask) { // Note: hard reset required due to soft reboot issue. #ifdef I2C1 diff --git a/shared-bindings/busio/I2C.h b/shared-bindings/busio/I2C.h index c5352fd66c..0999865fbf 100644 --- a/shared-bindings/busio/I2C.h +++ b/shared-bindings/busio/I2C.h @@ -60,16 +60,16 @@ extern void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self); extern bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr); // Write to the device and return 0 on success or an appropriate error code from mperrno.h -extern uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint8_t address, +extern uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, const uint8_t *data, size_t len); // Reads memory of the i2c device picking up where it left off and return 0 on // success or an appropriate error code from mperrno.h -extern uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint8_t address, +extern uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, uint8_t *data, size_t len); // Do a write and then a read in the same I2C transaction. -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint8_t address, +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t address, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len); // This is used by the supervisor to claim I2C devices indefinitely. diff --git a/shared-module/adafruit_bus_device/i2c_device/I2CDevice.c b/shared-module/adafruit_bus_device/i2c_device/I2CDevice.c index 0b430d1ea2..a630f1e2b8 100644 --- a/shared-module/adafruit_bus_device/i2c_device/I2CDevice.c +++ b/shared-module/adafruit_bus_device/i2c_device/I2CDevice.c @@ -79,7 +79,7 @@ void common_hal_adafruit_bus_device_i2cdevice_probe_for_device(adafruit_bus_devi common_hal_adafruit_bus_device_i2cdevice_unlock(self); if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t *)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_OSError))) { - mp_raise_ValueError_varg(translate("No I2C device at address: %x"), self->device_address); + mp_raise_ValueError_varg(translate("No I2C device at address: 0x%x"), self->device_address); } else { /* In case we receive an unrelated exception pass it up */ nlr_raise(MP_OBJ_FROM_PTR(nlr.ret_val)); diff --git a/shared-module/is31fl3741/IS31FL3741.c b/shared-module/is31fl3741/IS31FL3741.c index 9d7316e1cd..713dc44fd7 100644 --- a/shared-module/is31fl3741/IS31FL3741.c +++ b/shared-module/is31fl3741/IS31FL3741.c @@ -106,9 +106,8 @@ void common_hal_is31fl3741_IS31FL3741_reconstruct(is31fl3741_IS31FL3741_obj_t *s common_hal_displayio_is31fl3741_begin_transaction(self); uint8_t command = 0xFC; // device ID - common_hal_busio_i2c_write(self->i2c, self->device_address, &command, 1, false); uint8_t data = 0; - common_hal_busio_i2c_read(self->i2c, self->device_address, &data, 1); + common_hal_busio_i2c_write_read(self->i2c, self->device_address, &command, 1, &data, 1); is31fl3741_send_reset(self->i2c, self->device_address); is31fl3741_send_enable(self->i2c, self->device_address); @@ -275,7 +274,7 @@ uint8_t cur_page = 99; // set to invalid page to start void is31fl3741_send_unlock(busio_i2c_obj_t *i2c, uint8_t addr) { uint8_t unlock[2] = { 0xFE, 0xC5 }; // unlock command - common_hal_busio_i2c_write(i2c, addr, unlock, 2, true); + common_hal_busio_i2c_write(i2c, addr, unlock, 2); } void is31fl3741_set_page(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t p) { @@ -288,35 +287,33 @@ void is31fl3741_set_page(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t p) { uint8_t page[2] = { 0xFD, 0x00 }; // page command page[1] = p; - common_hal_busio_i2c_write(i2c, addr, page, 2, true); + common_hal_busio_i2c_write(i2c, addr, page, 2); } void is31fl3741_send_enable(busio_i2c_obj_t *i2c, uint8_t addr) { is31fl3741_set_page(i2c, addr, 4); uint8_t enable[2] = { 0x00, 0x01 }; // enable command - common_hal_busio_i2c_write(i2c, addr, enable, 2, true); + common_hal_busio_i2c_write(i2c, addr, enable, 2); } void is31fl3741_send_reset(busio_i2c_obj_t *i2c, uint8_t addr) { is31fl3741_set_page(i2c, addr, 4); uint8_t rst[2] = { 0x3F, 0xAE }; // reset command - common_hal_busio_i2c_write(i2c, addr, rst, 2, true); + common_hal_busio_i2c_write(i2c, addr, rst, 2); } void is31fl3741_set_current(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t current) { is31fl3741_set_page(i2c, addr, 4); uint8_t gcur[2] = { 0x01, 0x00 }; // global current command gcur[1] = current; - common_hal_busio_i2c_write(i2c, addr, gcur, 2, true); + common_hal_busio_i2c_write(i2c, addr, gcur, 2); } uint8_t is31fl3741_get_current(busio_i2c_obj_t *i2c, uint8_t addr) { is31fl3741_set_page(i2c, addr, 4); uint8_t gcur = 0x01; // global current command - common_hal_busio_i2c_write(i2c, addr, &gcur, 1, true); - uint8_t data = 0; - common_hal_busio_i2c_read(i2c, addr, &data, 1); + common_hal_busio_i2c_write_read(i2c, addr, &gcur, 1, &data, 1); return data; } @@ -333,7 +330,7 @@ void is31fl3741_set_led(busio_i2c_obj_t *i2c, uint8_t addr, uint16_t led, uint8_ cmd[1] = level; - common_hal_busio_i2c_write(i2c, addr, cmd, 2, true); + common_hal_busio_i2c_write(i2c, addr, cmd, 2); } void is31fl3741_draw_pixel(busio_i2c_obj_t *i2c, uint8_t addr, int16_t x, int16_t y, uint32_t color, uint16_t *mapping) { From d0453f460da5e27ddb084c5a29a1e270b40d963c Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 1 Feb 2022 10:12:26 -0500 Subject: [PATCH 3/3] shrink sensebox; fix doc error --- ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk | 1 + shared-bindings/busio/I2C.c | 1 + 2 files changed, 2 insertions(+) diff --git a/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk b/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk index bdfe26068d..f59483a608 100644 --- a/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk @@ -13,3 +13,4 @@ CIRCUITPY_FULL_BUILD = 0 # There are many pin definitions on this board; it doesn't quite fit on very large translations. # Remove a couple of modules. CIRCUITPY_ONEWIREIO = 0 +CIRCUITPY_RAINBOWIO = 0 diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c index a1abb4a72e..2d67281df0 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -58,6 +58,7 @@ //| :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`) +//| """ //| ... //| 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) {