stm32/i2c: Support setting the I2C TIMINGR value via keyword arg.

On MCUs that have an I2C TIMINGR register, this can now be explicitly set
via the "timingr" keyword argument to the I2C constructor, for both
machine.I2C and pyb.I2C.  This allows to configure precise timing values
when the defaults are inadequate.
This commit is contained in:
Damien George
2019-05-21 13:45:17 +10:00
parent ddc657658a
commit c769da1aaa
2 changed files with 43 additions and 3 deletions

View File

@@ -187,15 +187,24 @@ STATIC void machine_hard_i2c_init(machine_hard_i2c_obj_t *self, uint32_t freq, u
/******************************************************************************/
/* MicroPython bindings for machine API */
#if defined(STM32F0) || defined(STM32F7)
#define MACHINE_I2C_TIMINGR (1)
#else
#define MACHINE_I2C_TIMINGR (0)
#endif
mp_obj_t machine_hard_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
// parse args
enum { ARG_id, ARG_scl, ARG_sda, ARG_freq, ARG_timeout };
enum { ARG_id, ARG_scl, ARG_sda, ARG_freq, ARG_timeout, ARG_timingr };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_scl, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_sda, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = I2C_POLL_DEFAULT_TIMEOUT_US} },
#if MACHINE_I2C_TIMINGR
{ MP_QSTR_timingr, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
#endif
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -241,6 +250,13 @@ mp_obj_t machine_hard_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz
// initialise the I2C peripheral
machine_hard_i2c_init(self, args[ARG_freq].u_int, args[ARG_timeout].u_int);
#if MACHINE_I2C_TIMINGR
// If given, explicitly set the TIMINGR value
if (args[ARG_timingr].u_obj != mp_const_none) {
self->i2c->TIMINGR = mp_obj_get_int_truncated(args[ARG_timingr].u_obj);
}
#endif
return MP_OBJ_FROM_PTR(self);
}