summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2018-03-07 14:59:03 +1100
committerDamien George <damien.p.george@gmail.com>2018-03-07 14:59:03 +1100
commit024edafea06ef92ebd2c2be7131e2a12f9dfc54b (patch)
tree0572e1cef482893c947bfd1e9e004c742b0a33ca
parent8359210e71ee0c46434ef8b1056627597f0bf0bf (diff)
stm32/i2c: On F4 MCUs report the actual I2C SCL frequency.
-rw-r--r--ports/stm32/i2c.c18
-rw-r--r--ports/stm32/i2c.h2
-rw-r--r--ports/stm32/machine_i2c.c2
3 files changed, 15 insertions, 7 deletions
diff --git a/ports/stm32/i2c.c b/ports/stm32/i2c.c
index 56c63684f..b9ab16e12 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 f416c791e..e17621f7c 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 1018a9b1a..5822b8e67 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);
}