aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2024-09-22 21:19:59 -0400
committerKevin O'Connor <kevin@koconnor.net>2024-09-22 22:14:47 -0400
commit064eee6859e16589235fad7e425b51ade408e9bd (patch)
tree2c153456eea2bfc1998d3124cd9b7d126c45d83e
parent8b7cc439529d727944589b751bd3a00305976bd0 (diff)
downloadkutter-064eee6859e16589235fad7e425b51ade408e9bd.tar.gz
kutter-064eee6859e16589235fad7e425b51ade408e9bd.tar.xz
kutter-064eee6859e16589235fad7e425b51ade408e9bd.zip
stm32: Fix i2c clock speeds for chips with a peripheral clock over 48Mhz
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--src/stm32/stm32f0_i2c.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/stm32/stm32f0_i2c.c b/src/stm32/stm32f0_i2c.c
index 1382cd86..a45aa34b 100644
--- a/src/stm32/stm32f0_i2c.c
+++ b/src/stm32/stm32f0_i2c.c
@@ -148,11 +148,19 @@ i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr)
gpio_peripheral(ii->sda_pin, ii->function | GPIO_OPEN_DRAIN, 1);
// Set 100Khz frequency and enable
- i2c->TIMINGR = ((0xB << I2C_TIMINGR_PRESC_Pos)
- | (0x13 << I2C_TIMINGR_SCLL_Pos)
- | (0xF << I2C_TIMINGR_SCLH_Pos)
- | (0x2 << I2C_TIMINGR_SDADEL_Pos)
- | (0x4 << I2C_TIMINGR_SCLDEL_Pos));
+ uint32_t nom_i2c_clock = 8000000; // 8mhz internal clock = 125ns ticks
+ uint32_t scll = 40; // 40 * 125ns = 5us
+ uint32_t sclh = 32; // 32 * 125ns = 4us
+ uint32_t sdadel = 4; // 4 * 125ns = 500ns
+ uint32_t scldel = 10; // 10 * 125ns = 1250ns
+
+ uint32_t pclk = get_pclock_frequency((uint32_t)i2c);
+ uint32_t presc = DIV_ROUND_UP(pclk, nom_i2c_clock);
+ i2c->TIMINGR = (((presc - 1) << I2C_TIMINGR_PRESC_Pos)
+ | ((scll - 1) << I2C_TIMINGR_SCLL_Pos)
+ | ((sclh - 1) << I2C_TIMINGR_SCLH_Pos)
+ | (sdadel << I2C_TIMINGR_SDADEL_Pos)
+ | ((scldel - 1) << I2C_TIMINGR_SCLDEL_Pos));
i2c->CR1 = I2C_CR1_PE;
}