Skip to content

Commit eec8a94

Browse files
committed
extmod/machine_i2c: Implement I2C memory reading/writing.
1 parent 9314b2d commit eec8a94

2 files changed

Lines changed: 110 additions & 6 deletions

File tree

extmod/machine_i2c.c

Lines changed: 106 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,55 @@ STATIC void mp_hal_i2c_read(machine_i2c_obj_t *self, uint8_t addr, uint8_t *data
188188
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "I2C bus error"));
189189
}
190190

191+
STATIC void mp_hal_i2c_write_mem(machine_i2c_obj_t *self, uint8_t addr, uint16_t memaddr, const uint8_t *src, size_t len) {
192+
// start the I2C transaction
193+
mp_hal_i2c_start(self);
194+
195+
// write the slave address and the memory address within the slave
196+
if (!mp_hal_i2c_write_byte(self, addr << 1)) {
197+
goto er;
198+
}
199+
if (!mp_hal_i2c_write_byte(self, memaddr)) {
200+
goto er;
201+
}
202+
203+
// write the buffer to the I2C memory
204+
while (len--) {
205+
if (!mp_hal_i2c_write_byte(self, *src++)) {
206+
goto er;
207+
}
208+
}
209+
210+
// finish the I2C transaction
211+
mp_hal_i2c_stop(self);
212+
return;
213+
214+
er:
215+
mp_hal_i2c_stop(self);
216+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "I2C bus error"));
217+
}
218+
219+
STATIC void mp_hal_i2c_read_mem(machine_i2c_obj_t *self, uint8_t addr, uint16_t memaddr, uint8_t *dest, size_t len) {
220+
// start the I2C transaction
221+
mp_hal_i2c_start(self);
222+
223+
// write the slave address and the memory address within the slave
224+
if (!mp_hal_i2c_write_byte(self, addr << 1)) {
225+
goto er;
226+
}
227+
if (!mp_hal_i2c_write_byte(self, memaddr)) {
228+
goto er;
229+
}
230+
231+
// i2c_read will do a repeated start, and then read the I2C memory
232+
mp_hal_i2c_read(self, addr, dest, len);
233+
return;
234+
235+
er:
236+
mp_hal_i2c_stop(self);
237+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "I2C bus error"));
238+
}
239+
191240
/******************************************************************************/
192241
// MicroPython bindings for I2C
193242

@@ -316,18 +365,69 @@ STATIC mp_obj_t machine_i2c_writeto(mp_obj_t self_in, mp_obj_t addr_in, mp_obj_t
316365
}
317366
STATIC MP_DEFINE_CONST_FUN_OBJ_3(machine_i2c_writeto_obj, machine_i2c_writeto);
318367

319-
STATIC mp_obj_t machine_i2c_readfrom_mem(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
320-
mp_not_implemented("I2C.readfrom_mem");
368+
STATIC mp_obj_t machine_i2c_readfrom_mem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
369+
enum { ARG_addr, ARG_memaddr, ARG_n, ARG_addrsize };
370+
static const mp_arg_t allowed_args[] = {
371+
{ MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
372+
{ MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
373+
{ MP_QSTR_n, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
374+
//{ MP_QSTR_addrsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, TODO
375+
};
376+
machine_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
377+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
378+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
379+
380+
// create the buffer to store data into
381+
vstr_t vstr;
382+
vstr_init_len(&vstr, args[ARG_n].u_int);
383+
384+
// do the transfer
385+
mp_hal_i2c_read_mem(self, args[ARG_addr].u_int, args[ARG_memaddr].u_int, (uint8_t*)vstr.buf, vstr.len);
386+
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
321387
}
322388
MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_readfrom_mem_obj, 1, machine_i2c_readfrom_mem);
323389

324-
STATIC mp_obj_t machine_i2c_readfrom_mem_into(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
325-
mp_not_implemented("I2C.readfrom_mem_into");
390+
STATIC mp_obj_t machine_i2c_readfrom_mem_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
391+
enum { ARG_addr, ARG_memaddr, ARG_buf, ARG_addrsize };
392+
static const mp_arg_t allowed_args[] = {
393+
{ MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
394+
{ MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
395+
{ MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
396+
//{ MP_QSTR_addrsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, TODO
397+
};
398+
machine_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
399+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
400+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
401+
402+
// get the buffer to store data into
403+
mp_buffer_info_t bufinfo;
404+
mp_get_buffer_raise(args[ARG_buf].u_obj, &bufinfo, MP_BUFFER_WRITE);
405+
406+
// do the transfer
407+
mp_hal_i2c_read_mem(self, args[ARG_addr].u_int, args[ARG_memaddr].u_int, bufinfo.buf, bufinfo.len);
408+
return mp_const_none;
326409
}
327410
MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_readfrom_mem_into_obj, 1, machine_i2c_readfrom_mem_into);
328411

329-
STATIC mp_obj_t machine_i2c_writeto_mem(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
330-
mp_not_implemented("I2C.writeto_mem");
412+
STATIC mp_obj_t machine_i2c_writeto_mem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
413+
enum { ARG_addr, ARG_memaddr, ARG_buf, ARG_addrsize };
414+
static const mp_arg_t allowed_args[] = {
415+
{ MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
416+
{ MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
417+
{ MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
418+
//{ MP_QSTR_addrsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, TODO
419+
};
420+
machine_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
421+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
422+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
423+
424+
// get the buffer to write the data from
425+
mp_buffer_info_t bufinfo;
426+
mp_get_buffer_raise(args[ARG_buf].u_obj, &bufinfo, MP_BUFFER_READ);
427+
428+
// do the transfer
429+
mp_hal_i2c_write_mem(self, args[ARG_addr].u_int, args[ARG_memaddr].u_int, bufinfo.buf, bufinfo.len);
430+
return mp_const_none;
331431
}
332432
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_writeto_mem_obj, 1, machine_i2c_writeto_mem);
333433

py/qstrdefs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,10 @@ Q(writeto)
699699
Q(readfrom_mem)
700700
Q(readfrom_mem_into)
701701
Q(writeto_mem)
702+
Q(addr)
703+
Q(memaddr)
704+
Q(n)
705+
Q(buf)
702706
#endif
703707

704708
#if MICROPY_PY_USSL

0 commit comments

Comments
 (0)