aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2022-06-01 11:57:20 +1000
committerDamien George <damien@micropython.org>2022-06-01 13:20:27 +1000
commit4a1ae99ac384878ffaddb30e9f8139f7b07aabae (patch)
tree312231505744309b0e0f97dd437bfcd0b6a2f460
parentea9a904b7250ece017144c0d25a1569714a792b6 (diff)
extmod/machine_i2c: Add optional support for write-then-read transfers.
This option is useful for ports where it's more efficient to do a full I2C transfer in one go. Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r--extmod/machine_i2c.c17
-rw-r--r--extmod/machine_i2c.h5
-rw-r--r--py/mpconfig.h5
3 files changed, 27 insertions, 0 deletions
diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c
index f2c959b95..7d0628a2d 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 9e4374732..a211aef52 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 00890942b..ea03ad140 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)