esp8266: Implement bit-bang I2C read, and add i2c.readfrom method.
I2C reading tested with TSL2561 luminosity sensor.
This commit is contained in:
parent
5b9f361824
commit
0cdbd356fd
|
@ -186,6 +186,52 @@ er:
|
|||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "I2C bus error"));
|
||||
}
|
||||
|
||||
STATIC int mphal_i2c_read_byte(pyb_i2c_obj_t *self, uint8_t *val) {
|
||||
mphal_i2c_wait_a();
|
||||
mphal_i2c_set_scl(self, 0);
|
||||
mphal_i2c_wait_a();
|
||||
|
||||
uint8_t dat = 0;
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
mphal_i2c_set_scl(self, 1);
|
||||
mphal_i2c_wait_a();
|
||||
dat = (dat << 1) | mphal_i2c_get_sda(self);
|
||||
mphal_i2c_wait_a();
|
||||
mphal_i2c_set_scl(self, 0);
|
||||
mphal_i2c_wait_a();
|
||||
}
|
||||
*val = dat;
|
||||
|
||||
mphal_i2c_wait_a();
|
||||
mphal_i2c_set_scl(self, 1);
|
||||
mphal_i2c_wait_a();
|
||||
mphal_i2c_wait_b();
|
||||
mphal_i2c_set_scl(self, 0);
|
||||
mphal_i2c_wait_a();
|
||||
|
||||
return 1; // success
|
||||
}
|
||||
|
||||
STATIC void mphal_i2c_read(pyb_i2c_obj_t *self, uint8_t addr, uint8_t *data, size_t len, bool stop) {
|
||||
mphal_i2c_start(self);
|
||||
if (!mphal_i2c_write_byte(self, (addr << 1) | 1)) {
|
||||
goto er;
|
||||
}
|
||||
while (len--) {
|
||||
if (!mphal_i2c_read_byte(self, data++)) {
|
||||
goto er;
|
||||
}
|
||||
}
|
||||
if (stop) {
|
||||
mphal_i2c_stop(self);
|
||||
}
|
||||
return;
|
||||
|
||||
er:
|
||||
mphal_i2c_stop(self);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "I2C bus error"));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// MicroPython bindings for I2C
|
||||
|
||||
|
@ -219,6 +265,26 @@ STATIC mp_obj_t pyb_i2c_obj_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_
|
|||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_init_obj, 1, pyb_i2c_obj_init);
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_readfrom(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_addr, ARG_n, ARG_stop };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_n, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
|
||||
};
|
||||
pyb_i2c_obj_t *self = pos_args[0];
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// do the I2C transfer
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, args[ARG_n].u_int);
|
||||
mphal_i2c_read(self, args[ARG_addr].u_int, (uint8_t*)vstr.buf, vstr.len, args[ARG_stop].u_bool);
|
||||
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_readfrom_obj, 1, pyb_i2c_readfrom);
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_writeto(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_addr, ARG_buf, ARG_stop };
|
||||
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);
|
|||
|
||||
STATIC const mp_rom_map_elem_t pyb_i2c_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_i2c_init_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readfrom), MP_ROM_PTR(&pyb_i2c_readfrom_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_writeto), MP_ROM_PTR(&pyb_i2c_writeto_obj) },
|
||||
};
|
||||
|
||||
|
|
|
@ -148,10 +148,12 @@ Q(init)
|
|||
Q(scl)
|
||||
Q(sda)
|
||||
Q(freq)
|
||||
Q(readfrom)
|
||||
Q(writeto)
|
||||
Q(stop)
|
||||
Q(buf)
|
||||
Q(addr)
|
||||
Q(n)
|
||||
|
||||
// utime
|
||||
Q(utime)
|
||||
|
|
Loading…
Reference in New Issue