Browse Source

stm32/i2c: Add support for I2C4 on H7 MCUs.

The current code assumes all I2Cs are on the same peripheral bus, which is
not true for I2C4 and the same goes for the clock enable code.

Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
pull/12578/head
iabdalkader 1 year ago
committed by Damien George
parent
commit
5aec051f9f
  1. 34
      ports/stm32/i2c.c

34
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 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) { 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 // 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)) { 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; i2c_timeout_ms[i2c_id] = timeout_ms;
// Enable I2C peripheral clock // Enable I2C peripheral clock
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN << i2c_id; volatile uint32_t tmp;
volatile uint32_t tmp = RCC->APB1ENR; // delay after RCC clock enable
(void)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 // Initialise I2C peripheral
i2c->CR1 = 0; 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) { 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(); uint32_t t0 = HAL_GetTick();
while (i2c->CR2 & mask) { while (i2c->CR2 & mask) {
if (HAL_GetTick() - t0 >= i2c_timeout_ms[i2c_id]) { 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) { 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(); uint32_t t0 = HAL_GetTick();
while (!(i2c->ISR & mask)) { while (!(i2c->ISR & mask)) {
if (HAL_GetTick() - t0 >= i2c_timeout_ms[i2c_id]) { if (HAL_GetTick() - t0 >= i2c_timeout_ms[i2c_id]) {

Loading…
Cancel
Save