diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c index f2c959b95a..7d0628a2d4 100644 --- a/extmod/machine_i2c.c +++ b/extmod/machine_i2c.c @@ -514,6 +514,21 @@ STATIC int read_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t a uint8_t memaddr_buf[4]; size_t memaddr_len = fill_memaddr_buf(&memaddr_buf[0], memaddr, addrsize); + #if MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1 + + // Create partial write and read buffers + mp_machine_i2c_buf_t bufs[2] = { + {.len = memaddr_len, .buf = memaddr_buf}, + {.len = len, .buf = buf}, + }; + + // Do write+read I2C transfer + mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; + return i2c_p->transfer(self, addr, 2, bufs, + MP_MACHINE_I2C_FLAG_WRITE1 | MP_MACHINE_I2C_FLAG_READ | MP_MACHINE_I2C_FLAG_STOP); + + #else + int ret = mp_machine_i2c_writeto(self, addr, memaddr_buf, memaddr_len, false); if (ret != memaddr_len) { // must generate STOP @@ -521,6 +536,8 @@ STATIC int read_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t a return ret; } return mp_machine_i2c_readfrom(self, addr, buf, len, true); + + #endif } STATIC int write_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t addrsize, const uint8_t *buf, size_t len) { diff --git a/extmod/machine_i2c.h b/extmod/machine_i2c.h index 9e43747323..a211aef527 100644 --- a/extmod/machine_i2c.h +++ b/extmod/machine_i2c.h @@ -45,6 +45,11 @@ #define MP_MACHINE_I2C_FLAG_READ (0x01) // if not set then it's a write #define MP_MACHINE_I2C_FLAG_STOP (0x02) +#if MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1 +// If set, the first mp_machine_i2c_buf_t in a transfer is a write. +#define MP_MACHINE_I2C_FLAG_WRITE1 (0x04) +#endif + typedef struct _mp_machine_i2c_buf_t { size_t len; uint8_t *buf; diff --git a/py/mpconfig.h b/py/mpconfig.h index 00890942bb..ea03ad1408 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1585,6 +1585,11 @@ typedef double mp_float_t; #define MICROPY_PY_MACHINE_I2C (0) #endif +// Whether the low-level I2C transfer function supports a separate write as the first transfer +#ifndef MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1 +#define MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1 (0) +#endif + // Whether to provide the "machine.SoftI2C" class #ifndef MICROPY_PY_MACHINE_SOFTI2C #define MICROPY_PY_MACHINE_SOFTI2C (0)