summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/i2c.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/ports/stm32/i2c.c b/ports/stm32/i2c.c
index 65271b352..42aba2ecc 100644
--- a/ports/stm32/i2c.c
+++ b/ports/stm32/i2c.c
@@ -285,8 +285,17 @@ int i2c_write(i2c_t *i2c, const uint8_t *src, size_t len, size_t next_len) {
STATIC uint16_t i2c_timeout_ms[MICROPY_HW_MAX_I2C];
+static uint32_t i2c_get_id(i2c_t *i2c) {
+ #if defined(STM32H7)
+ if (i2c == I2C4) {
+ return 3;
+ }
+ #endif
+ return ((uint32_t)i2c - I2C1_BASE) / (I2C2_BASE - I2C1_BASE);
+}
+
int i2c_init(i2c_t *i2c, mp_hal_pin_obj_t scl, mp_hal_pin_obj_t sda, uint32_t freq, uint16_t timeout_ms) {
- uint32_t i2c_id = ((uint32_t)i2c - I2C1_BASE) / (I2C2_BASE - I2C1_BASE);
+ uint32_t i2c_id = i2c_get_id(i2c);
// Init pins
if (!mp_hal_pin_config_alt(scl, MP_HAL_PIN_MODE_ALT_OPEN_DRAIN, MP_HAL_PIN_PULL_UP, AF_FN_I2C, i2c_id + 1)) {
@@ -300,9 +309,22 @@ int i2c_init(i2c_t *i2c, mp_hal_pin_obj_t scl, mp_hal_pin_obj_t sda, uint32_t fr
i2c_timeout_ms[i2c_id] = timeout_ms;
// Enable I2C peripheral clock
- RCC->APB1ENR |= RCC_APB1ENR_I2C1EN << i2c_id;
- volatile uint32_t tmp = RCC->APB1ENR; // delay after RCC clock enable
+ volatile uint32_t tmp;
(void)tmp;
+ switch (i2c_id) {
+ case 0:
+ case 1:
+ case 2:
+ RCC->APB1ENR |= RCC_APB1ENR_I2C1EN << i2c_id;
+ tmp = RCC->APB1ENR; // delay after RCC clock enable
+ break;
+ #if defined(STM32H7)
+ case 3:
+ RCC->APB4ENR |= RCC_APB4ENR_I2C4EN;
+ tmp = RCC->APB4ENR; // delay after RCC clock enable
+ break;
+ #endif
+ }
// Initialise I2C peripheral
i2c->CR1 = 0;
@@ -340,7 +362,8 @@ int i2c_init(i2c_t *i2c, mp_hal_pin_obj_t scl, mp_hal_pin_obj_t sda, uint32_t fr
}
STATIC int i2c_wait_cr2_clear(i2c_t *i2c, uint32_t mask) {
- uint32_t i2c_id = ((uint32_t)i2c - I2C1_BASE) / (I2C2_BASE - I2C1_BASE);
+ uint32_t i2c_id = i2c_get_id(i2c);
+
uint32_t t0 = HAL_GetTick();
while (i2c->CR2 & mask) {
if (HAL_GetTick() - t0 >= i2c_timeout_ms[i2c_id]) {
@@ -352,7 +375,8 @@ STATIC int i2c_wait_cr2_clear(i2c_t *i2c, uint32_t mask) {
}
STATIC int i2c_wait_isr_set(i2c_t *i2c, uint32_t mask) {
- uint32_t i2c_id = ((uint32_t)i2c - I2C1_BASE) / (I2C2_BASE - I2C1_BASE);
+ uint32_t i2c_id = i2c_get_id(i2c);
+
uint32_t t0 = HAL_GetTick();
while (!(i2c->ISR & mask)) {
if (HAL_GetTick() - t0 >= i2c_timeout_ms[i2c_id]) {