diff options
author | Damien George <damien.p.george@gmail.com> | 2019-05-21 13:45:17 +1000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2019-05-21 13:45:17 +1000 |
commit | c769da1aaa28fb0eba9fabfba84c39cbc09e23da (patch) | |
tree | b9e018a0842f148bb9c59e7dc8b8c07839d28aa5 /ports/stm32/pyb_i2c.c | |
parent | ddc657658af9ef74a7d891700a6e576c4fb5ff8e (diff) |
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.
Diffstat (limited to 'ports/stm32/pyb_i2c.c')
-rw-r--r-- | ports/stm32/pyb_i2c.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c index 233cbba51..8b816a25b 100644 --- a/ports/stm32/pyb_i2c.c +++ b/ports/stm32/pyb_i2c.c @@ -135,6 +135,8 @@ const pyb_i2c_obj_t pyb_i2c_obj[] = { // The STM32F0, F3, F7, H7 and L4 use a TIMINGR register rather than ClockSpeed and // DutyCycle. +#define PYB_I2C_TIMINGR (1) + #if defined(STM32F746xx) // The value 0x40912732 was obtained from the DISCOVERY_I2Cx_TIMING constant @@ -213,6 +215,8 @@ uint32_t pyb_i2c_get_baudrate(I2C_HandleTypeDef *i2c) { #else +#define PYB_I2C_TIMINGR (0) + #define MICROPY_HW_I2C_BAUDRATE_DEFAULT (PYB_I2C_SPEED_FULL) #define MICROPY_HW_I2C_BAUDRATE_MAX (PYB_I2C_SPEED_FULL) @@ -564,7 +568,15 @@ STATIC void pyb_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki mp_printf(print, "I2C(%u)", i2c_num); } else { if (in_master_mode(self)) { - mp_printf(print, "I2C(%u, I2C.MASTER, baudrate=%u)", i2c_num, pyb_i2c_get_baudrate(self->i2c)); + mp_printf(print, "I2C(%u, I2C.MASTER, baudrate=%u" + #if PYB_I2C_TIMINGR + ", timingr=0x%08x" + #endif + ")", i2c_num, pyb_i2c_get_baudrate(self->i2c) + #if PYB_I2C_TIMINGR + , self->i2c->Init.Timing + #endif + ); } else { mp_printf(print, "I2C(%u, I2C.SLAVE, addr=0x%02x)", i2c_num, (self->i2c->Instance->OAR1 >> 1) & 0x7f); } @@ -586,6 +598,9 @@ STATIC mp_obj_t pyb_i2c_init_helper(const pyb_i2c_obj_t *self, size_t n_args, co { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = MICROPY_HW_I2C_BAUDRATE_DEFAULT} }, { MP_QSTR_gencall, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_dma, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + #if PYB_I2C_TIMINGR + { MP_QSTR_timingr, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + #endif }; // parse args @@ -602,7 +617,16 @@ STATIC mp_obj_t pyb_i2c_init_helper(const pyb_i2c_obj_t *self, size_t n_args, co init->OwnAddress1 = (args[1].u_int << 1) & 0xfe; } - i2c_set_baudrate(init, MIN(args[2].u_int, MICROPY_HW_I2C_BAUDRATE_MAX)); + // Set baudrate or timing value (if supported) + #if PYB_I2C_TIMINGR + if (args[5].u_obj != mp_const_none) { + init->Timing = mp_obj_get_int_truncated(args[5].u_obj); + } else + #endif + { + i2c_set_baudrate(init, MIN(args[2].u_int, MICROPY_HW_I2C_BAUDRATE_MAX)); + } + init->AddressingMode = I2C_ADDRESSINGMODE_7BIT; init->DualAddressMode = I2C_DUALADDRESS_DISABLED; init->GeneralCallMode = args[3].u_bool ? I2C_GENERALCALL_ENABLED : I2C_GENERALCALL_DISABLED; |