@@ -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}
317366STATIC 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}
322388MP_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}
327410MP_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}
332432STATIC MP_DEFINE_CONST_FUN_OBJ_KW (machine_i2c_writeto_mem_obj , 1 , machine_i2c_writeto_mem );
333433
0 commit comments