@@ -186,6 +186,52 @@ STATIC void mphal_i2c_write(pyb_i2c_obj_t *self, uint8_t addr, uint8_t *data, si
186186 nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , "I2C bus error" ));
187187}
188188
189+ STATIC int mphal_i2c_read_byte (pyb_i2c_obj_t * self , uint8_t * val ) {
190+ mphal_i2c_wait_a ();
191+ mphal_i2c_set_scl (self , 0 );
192+ mphal_i2c_wait_a ();
193+
194+ uint8_t dat = 0 ;
195+ for (int i = 7 ; i >= 0 ; i -- ) {
196+ mphal_i2c_set_scl (self , 1 );
197+ mphal_i2c_wait_a ();
198+ dat = (dat << 1 ) | mphal_i2c_get_sda (self );
199+ mphal_i2c_wait_a ();
200+ mphal_i2c_set_scl (self , 0 );
201+ mphal_i2c_wait_a ();
202+ }
203+ * val = dat ;
204+
205+ mphal_i2c_wait_a ();
206+ mphal_i2c_set_scl (self , 1 );
207+ mphal_i2c_wait_a ();
208+ mphal_i2c_wait_b ();
209+ mphal_i2c_set_scl (self , 0 );
210+ mphal_i2c_wait_a ();
211+
212+ return 1 ; // success
213+ }
214+
215+ STATIC void mphal_i2c_read (pyb_i2c_obj_t * self , uint8_t addr , uint8_t * data , size_t len , bool stop ) {
216+ mphal_i2c_start (self );
217+ if (!mphal_i2c_write_byte (self , (addr << 1 ) | 1 )) {
218+ goto er ;
219+ }
220+ while (len -- ) {
221+ if (!mphal_i2c_read_byte (self , data ++ )) {
222+ goto er ;
223+ }
224+ }
225+ if (stop ) {
226+ mphal_i2c_stop (self );
227+ }
228+ return ;
229+
230+ er :
231+ mphal_i2c_stop (self );
232+ nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , "I2C bus error" ));
233+ }
234+
189235/******************************************************************************/
190236// MicroPython bindings for I2C
191237
@@ -219,6 +265,26 @@ STATIC mp_obj_t pyb_i2c_obj_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_
219265}
220266MP_DEFINE_CONST_FUN_OBJ_KW (pyb_i2c_init_obj , 1 , pyb_i2c_obj_init );
221267
268+ STATIC mp_obj_t pyb_i2c_readfrom (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
269+ enum { ARG_addr , ARG_n , ARG_stop };
270+ static const mp_arg_t allowed_args [] = {
271+ { MP_QSTR_addr , MP_ARG_REQUIRED | MP_ARG_INT , {.u_int = 0 } },
272+ { MP_QSTR_n , MP_ARG_REQUIRED | MP_ARG_INT , {.u_int = 0 } },
273+ { MP_QSTR_stop , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = true} },
274+ };
275+ pyb_i2c_obj_t * self = pos_args [0 ];
276+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
277+ mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
278+
279+ // do the I2C transfer
280+ vstr_t vstr ;
281+ vstr_init_len (& vstr , args [ARG_n ].u_int );
282+ mphal_i2c_read (self , args [ARG_addr ].u_int , (uint8_t * )vstr .buf , vstr .len , args [ARG_stop ].u_bool );
283+
284+ return mp_obj_new_str_from_vstr (& mp_type_bytes , & vstr );
285+ }
286+ MP_DEFINE_CONST_FUN_OBJ_KW (pyb_i2c_readfrom_obj , 1 , pyb_i2c_readfrom );
287+
222288STATIC mp_obj_t pyb_i2c_writeto (mp_uint_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
223289 enum { ARG_addr , ARG_buf , ARG_stop };
224290 static const mp_arg_t allowed_args [] = {
@@ -243,6 +309,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_writeto_obj, 1, pyb_i2c_writeto);
243309
244310STATIC const mp_rom_map_elem_t pyb_i2c_locals_dict_table [] = {
245311 { MP_ROM_QSTR (MP_QSTR_init ), MP_ROM_PTR (& pyb_i2c_init_obj ) },
312+ { MP_ROM_QSTR (MP_QSTR_readfrom ), MP_ROM_PTR (& pyb_i2c_readfrom_obj ) },
246313 { MP_ROM_QSTR (MP_QSTR_writeto ), MP_ROM_PTR (& pyb_i2c_writeto_obj ) },
247314};
248315
0 commit comments