stm32/i2c: Add hardware I2C implementation for STM32L4.
For STM32L4, hardware I2C can be implemented by using TIMINGR. This commit enables: - Use of hardware I2C in machine.I2C. - Specifying a frequency greater than or equal to 400KHz with pyb.I2C.
This commit is contained in:
parent
d0bea69c5e
commit
e18e47fa81
@ -269,11 +269,18 @@ int i2c_write(i2c_t *i2c, const uint8_t *src, size_t len, size_t next_len) {
|
|||||||
return num_acks;
|
return num_acks;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(STM32F0) || defined(STM32F7) || defined(STM32H7)
|
#elif defined(STM32F0) || defined(STM32F7) || defined(STM32H7) || defined(STM32L4)
|
||||||
|
|
||||||
#if defined(STM32H7)
|
#if defined(STM32H7)
|
||||||
#define APB1ENR APB1LENR
|
#define APB1ENR APB1LENR
|
||||||
#define RCC_APB1ENR_I2C1EN RCC_APB1LENR_I2C1EN
|
#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
|
#endif
|
||||||
|
|
||||||
STATIC uint16_t i2c_timeout_ms[MICROPY_HW_MAX_I2C];
|
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->OAR1 = 0;
|
||||||
i2c->OAR2 = 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
|
// These timing values are for f_I2CCLK=54MHz and are only approximate
|
||||||
if (freq >= 1000000) {
|
if (freq >= 1000000) {
|
||||||
i2c->TIMINGR = 0x50100103;
|
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 {
|
} else {
|
||||||
return -MP_EINVAL;
|
return -MP_EINVAL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
i2c->TIMEOUTR = 0;
|
i2c->TIMEOUTR = 0;
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
#define I2C_POLL_DEFAULT_TIMEOUT_US (50000) // 50ms
|
#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 {
|
typedef struct _machine_hard_i2c_obj_t {
|
||||||
mp_obj_base_t base;
|
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 */
|
/* 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)
|
#define MACHINE_I2C_TIMINGR (1)
|
||||||
#else
|
#else
|
||||||
#define MACHINE_I2C_TIMINGR (0)
|
#define MACHINE_I2C_TIMINGR (0)
|
||||||
|
@ -208,11 +208,14 @@ const pyb_i2c_obj_t pyb_i2c_obj[] = {
|
|||||||
|
|
||||||
#elif defined(STM32L4)
|
#elif defined(STM32L4)
|
||||||
|
|
||||||
// The value 0x90112626 was obtained from the DISCOVERY_I2C1_TIMING constant
|
// generated using CubeMX
|
||||||
// defined in the STM32L4Cube file Drivers/BSP/STM32L476G-Discovery/stm32l476g_discovery.h
|
#define MICROPY_HW_I2C_BAUDRATE_TIMING { \
|
||||||
#define MICROPY_HW_I2C_BAUDRATE_TIMING {{PYB_I2C_SPEED_STANDARD, 0x90112626}}
|
{PYB_I2C_SPEED_STANDARD, 0x10909CEC}, \
|
||||||
#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (PYB_I2C_SPEED_STANDARD)
|
{PYB_I2C_SPEED_FULL, 0x00702991}, \
|
||||||
#define MICROPY_HW_I2C_BAUDRATE_MAX (PYB_I2C_SPEED_STANDARD)
|
{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
|
#else
|
||||||
#error "no I2C timings for this MCU"
|
#error "no I2C timings for this MCU"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user