diff --git a/ports/stm32/i2c.c b/ports/stm32/i2c.c index cb5ec56cb2f5..65271b352525 100644 --- a/ports/stm32/i2c.c +++ b/ports/stm32/i2c.c @@ -269,11 +269,18 @@ int i2c_write(i2c_t *i2c, const uint8_t *src, size_t len, size_t next_len) { return num_acks; } -#elif defined(STM32F0) || defined(STM32F7) || defined(STM32H7) +#elif defined(STM32F0) || defined(STM32F7) || defined(STM32H7) || defined(STM32L4) #if defined(STM32H7) #define APB1ENR APB1LENR #define RCC_APB1ENR_I2C1EN RCC_APB1LENR_I2C1EN +#elif defined(STM32L4) +#define APB1ENR APB1ENR1 +#define RCC_APB1ENR_I2C1EN RCC_APB1ENR1_I2C1EN +#if defined(STM32L432xx) +// Not a real peripheral, only needed for i2c_id calculation in i2c_init. +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800UL) +#endif #endif STATIC uint16_t i2c_timeout_ms[MICROPY_HW_MAX_I2C]; @@ -303,6 +310,18 @@ int i2c_init(i2c_t *i2c, mp_hal_pin_obj_t scl, mp_hal_pin_obj_t sda, uint32_t fr i2c->OAR1 = 0; i2c->OAR2 = 0; + #if defined(STM32L4) + // These timing values are with f_I2CCLK=80MHz and are only approximate + if (freq >= 1000000) { + i2c->TIMINGR = 0x00300F33; + } else if (freq >= 400000) { + i2c->TIMINGR = 0x00702991; + } else if (freq >= 100000) { + i2c->TIMINGR = 0x10909CEC; + } else { + return -MP_EINVAL; + } + #else // These timing values are for f_I2CCLK=54MHz and are only approximate if (freq >= 1000000) { i2c->TIMINGR = 0x50100103; @@ -313,6 +332,7 @@ int i2c_init(i2c_t *i2c, mp_hal_pin_obj_t scl, mp_hal_pin_obj_t sda, uint32_t fr } else { return -MP_EINVAL; } + #endif i2c->TIMEOUTR = 0; diff --git a/ports/stm32/machine_i2c.c b/ports/stm32/machine_i2c.c index 1af68bda9e5e..f4b0b3312562 100644 --- a/ports/stm32/machine_i2c.c +++ b/ports/stm32/machine_i2c.c @@ -38,7 +38,7 @@ #define I2C_POLL_DEFAULT_TIMEOUT_US (50000) // 50ms -#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32L1) +#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32L1) || defined(STM32L4) typedef struct _machine_hard_i2c_obj_t { mp_obj_base_t base; @@ -186,7 +186,7 @@ STATIC void machine_hard_i2c_init(machine_hard_i2c_obj_t *self, uint32_t freq, u /******************************************************************************/ /* MicroPython bindings for machine API */ -#if defined(STM32F0) || defined(STM32F7) || defined(STM32H7) +#if defined(STM32F0) || defined(STM32F7) || defined(STM32H7) || defined(STM32L4) #define MACHINE_I2C_TIMINGR (1) #else #define MACHINE_I2C_TIMINGR (0) diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c index 9aac9274e05f..89bd6b46dc13 100644 --- a/ports/stm32/pyb_i2c.c +++ b/ports/stm32/pyb_i2c.c @@ -208,11 +208,14 @@ const pyb_i2c_obj_t pyb_i2c_obj[] = { #elif defined(STM32L4) -// The value 0x90112626 was obtained from the DISCOVERY_I2C1_TIMING constant -// defined in the STM32L4Cube file Drivers/BSP/STM32L476G-Discovery/stm32l476g_discovery.h -#define MICROPY_HW_I2C_BAUDRATE_TIMING {{PYB_I2C_SPEED_STANDARD, 0x90112626}} -#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (PYB_I2C_SPEED_STANDARD) -#define MICROPY_HW_I2C_BAUDRATE_MAX (PYB_I2C_SPEED_STANDARD) +// generated using CubeMX +#define MICROPY_HW_I2C_BAUDRATE_TIMING { \ + {PYB_I2C_SPEED_STANDARD, 0x10909CEC}, \ + {PYB_I2C_SPEED_FULL, 0x00702991}, \ + {PYB_I2C_SPEED_FAST, 0x00300F33}, \ +} +#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (PYB_I2C_SPEED_FULL) +#define MICROPY_HW_I2C_BAUDRATE_MAX (PYB_I2C_SPEED_FAST) #else #error "no I2C timings for this MCU"