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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user