arch/arm/stm32/: Fix I2C driver for STM32G4 devices.

This commit is contained in:
Daniel P. Carvalho 2025-01-02 18:21:32 -03:00 committed by Xiang Xiao
parent 3f3e6dd9b8
commit ba32b61d2e
3 changed files with 50 additions and 6 deletions

View file

@ -670,11 +670,20 @@
#define STM32_RCC_APB1ENR_OFFSET STM32_RCC_APB1ENR1_OFFSET
#define STM32_RCC_APB1ENR STM32_RCC_APB1ENR1
#define STM32_RCC_APB1RSTR_OFFSET STM32_RCC_APB1RSTR1_OFFSET
#define STM32_RCC_APB1RSTR STM32_RCC_APB1RSTR1
#define RCC_APB1ENR_USART2EN RCC_APB1ENR1_USART2EN
#define RCC_APB1ENR_USART3EN RCC_APB1ENR1_USART3EN
#define RCC_APB1ENR_UART4EN RCC_APB1ENR1_UART4EN
#define RCC_APB1ENR_UART5EN RCC_APB1ENR1_UART5EN
#define RCC_APB1ENR_I2C1EN RCC_APB1ENR1_I2C1EN
#define RCC_APB1ENR_I2C2EN RCC_APB1ENR1_I2C2EN
#define RCC_APB1RSTR_I2C1RST RCC_APB1RSTR1_I2C1RST
#define RCC_APB1RSTR_I2C2RST RCC_APB1RSTR1_I2C2RST
#define RCC_APB1ENR_TIM2EN RCC_APB1ENR1_TIM2EN
#define RCC_APB1ENR_TIM3EN RCC_APB1ENR1_TIM3EN
#define RCC_APB1ENR_TIM4EN RCC_APB1ENR1_TIM4EN

View file

@ -61,7 +61,7 @@
* Unsupported, possible future work:
* - More effective error reporting to higher layers
* - Slave operation
* - Support of fI2CCLK frequencies other than 8Mhz
* - Support of fI2CCLK frequencies other than HSI
* - Polled operation (code present but untested)
* - SMBus support
* - Multi-master support
@ -251,6 +251,19 @@
#undef INVALID_CLOCK_SOURCE
#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX) || \
defined(CONFIG_STM32_STM32F37XX)
# if STM32_HSI_FREQUENCY != 8000000 || defined(INVALID_CLOCK_SOURCE)
# error STM32_I2C: Peripheral clock is HSI and it must be 8MHz or the speed/timing calculations need to be redone.
# endif
#elif defined(CONFIG_STM32_STM32G4XXX)
# if STM32_HSI_FREQUENCY != 16000000 || defined(INVALID_CLOCK_SOURCE)
# error STM32_I2C: Peripheral clock is HSI and it must be 16MHz or the speed/timing calculations need to be redone.
# endif
#else
# error STM32_I2C: Device not Supported.
#endif
#warning TODO: check I2C clock source. It must be HSI!
/* CONFIG_I2C_POLLED may be set so that I2C interrupts will not be used.
@ -2706,11 +2719,6 @@ struct i2c_master_s *stm32_i2cbus_initialize(int port)
struct stm32_i2c_priv_s *priv = NULL; /* private data of device with multiple instances */
struct stm32_i2c_inst_s *inst = NULL; /* device, single instance */
#if STM32_HSI_FREQUENCY != 8000000 || defined(INVALID_CLOCK_SOURCE)
# warning STM32_I2C_INIT: Peripheral clock is HSI and it must be 16mHz or the speed/timing calculations need to be redone.
return NULL;
#endif
/* Get I2C private structure */
switch (port)

View file

@ -955,6 +955,33 @@ static void stm32_stdclockconfig(void)
regval |= (STM32_RCC_CFGR_PPRE1 | STM32_RCC_CFGR_PPRE2);
putreg32(regval, STM32_RCC_CFGR);
/* Configure I2C source clock
*
* TODO:
* - Set to HSI16 by default, make Kconfig option
*/
#if defined(CONFIG_STM32_I2C1)
regval = getreg32(STM32_RCC_CCIPR);
regval &= ~RCC_CCIPR_I2C1SEL_MASK;
regval |= RCC_CCIPR_I2C1SEL_HSI16;
putreg32(regval, STM32_RCC_CCIPR);
#endif
#if defined(CONFIG_STM32_I2C2)
regval = getreg32(STM32_RCC_CCIPR);
regval &= ~RCC_CCIPR_I2C2SEL_MASK;
regval |= RCC_CCIPR_I2C2SEL_HSI16;
putreg32(regval, STM32_RCC_CCIPR);
#endif
#if defined(CONFIG_STM32_I2C3)
regval = getreg32(STM32_RCC_CCIPR);
regval &= ~RCC_CCIPR_I2C3SEL_MASK;
regval |= RCC_CCIPR_I2C3SEL_HSI16;
putreg32(regval, STM32_RCC_CCIPR);
#endif
/* Configure FDCAN source clock */
#if defined(STM32_CCIPR_FDCANSRC)