From 024edafea06ef92ebd2c2be7131e2a12f9dfc54b Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 7 Mar 2018 14:59:03 +1100 Subject: [PATCH] stm32/i2c: On F4 MCUs report the actual I2C SCL frequency. --- ports/stm32/i2c.c | 18 +++++++++++++----- ports/stm32/i2c.h | 2 +- ports/stm32/machine_i2c.c | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/ports/stm32/i2c.c b/ports/stm32/i2c.c index 56c63684f5..b9ab16e123 100644 --- a/ports/stm32/i2c.c +++ b/ports/stm32/i2c.c @@ -191,9 +191,9 @@ STATIC void i2c_set_baudrate(I2C_InitTypeDef *init, uint32_t baudrate) { "Unsupported I2C baudrate: %lu", baudrate)); } -uint32_t i2c_get_baudrate(I2C_InitTypeDef *init) { +uint32_t i2c_get_baudrate(I2C_HandleTypeDef *i2c) { for (int i = 0; i < NUM_BAUDRATE_TIMINGS; i++) { - if (pyb_i2c_baudrate_timing[i].timing == init->Timing) { + if (pyb_i2c_baudrate_timing[i].timing == i2c->Init.Timing) { return pyb_i2c_baudrate_timing[i].baudrate; } } @@ -210,8 +210,16 @@ STATIC void i2c_set_baudrate(I2C_InitTypeDef *init, uint32_t baudrate) { init->DutyCycle = I2C_DUTYCYCLE_16_9; } -uint32_t i2c_get_baudrate(I2C_InitTypeDef *init) { - return init->ClockSpeed; +uint32_t i2c_get_baudrate(I2C_HandleTypeDef *i2c) { + uint32_t pfreq = i2c->Instance->CR2 & 0x3f; + uint32_t ccr = i2c->Instance->CCR & 0xfff; + if (i2c->Instance->CCR & 0x8000) { + // Fast mode, assume duty cycle of 16/9 + return pfreq * 40000 / ccr; + } else { + // Standard mode + return pfreq * 500000 / ccr; + } } #endif @@ -545,7 +553,7 @@ 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, i2c_get_baudrate(&self->i2c->Init)); + mp_printf(print, "I2C(%u, I2C.MASTER, baudrate=%u)", i2c_num, i2c_get_baudrate(self->i2c)); } else { mp_printf(print, "I2C(%u, I2C.SLAVE, addr=0x%02x)", i2c_num, (self->i2c->Instance->OAR1 >> 1) & 0x7f); } diff --git a/ports/stm32/i2c.h b/ports/stm32/i2c.h index f416c791ee..e17621f7c3 100644 --- a/ports/stm32/i2c.h +++ b/ports/stm32/i2c.h @@ -48,7 +48,7 @@ extern const pyb_i2c_obj_t pyb_i2c_obj[4]; void i2c_init0(void); void i2c_init(I2C_HandleTypeDef *i2c); void i2c_init_freq(const pyb_i2c_obj_t *self, mp_int_t freq); -uint32_t i2c_get_baudrate(I2C_InitTypeDef *init); +uint32_t i2c_get_baudrate(I2C_HandleTypeDef *i2c); void i2c_ev_irq_handler(mp_uint_t i2c_id); void i2c_er_irq_handler(mp_uint_t i2c_id); diff --git a/ports/stm32/machine_i2c.c b/ports/stm32/machine_i2c.c index 1018a9b1a5..5822b8e672 100644 --- a/ports/stm32/machine_i2c.c +++ b/ports/stm32/machine_i2c.c @@ -88,7 +88,7 @@ STATIC void machine_hard_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp machine_hard_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "I2C(%u, freq=%u, timeout=%u)", self - &machine_hard_i2c_obj[0] + 1, - i2c_get_baudrate(&self->pyb->i2c->Init), + i2c_get_baudrate(self->pyb->i2c), *self->timeout); }