This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new ba32b61d2e arch/arm/stm32/: Fix I2C driver for STM32G4 devices.
ba32b61d2e is described below
commit ba32b61d2eeb27b04c5466236376604bfd5c7562
Author: Daniel P. Carvalho <[email protected]>
AuthorDate: Thu Jan 2 18:21:32 2025 -0300
arch/arm/stm32/: Fix I2C driver for STM32G4 devices.
---
arch/arm/src/stm32/hardware/stm32g4xxxx_rcc.h | 9 +++++++++
arch/arm/src/stm32/stm32_i2c_v2.c | 20 ++++++++++++++------
arch/arm/src/stm32/stm32g4xxxx_rcc.c | 27 +++++++++++++++++++++++++++
3 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/arch/arm/src/stm32/hardware/stm32g4xxxx_rcc.h
b/arch/arm/src/stm32/hardware/stm32g4xxxx_rcc.h
index f779cde0a6..543d369f3e 100644
--- a/arch/arm/src/stm32/hardware/stm32g4xxxx_rcc.h
+++ b/arch/arm/src/stm32/hardware/stm32g4xxxx_rcc.h
@@ -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
diff --git a/arch/arm/src/stm32/stm32_i2c_v2.c
b/arch/arm/src/stm32/stm32_i2c_v2.c
index aeebc3b4d1..0f88986feb 100644
--- a/arch/arm/src/stm32/stm32_i2c_v2.c
+++ b/arch/arm/src/stm32/stm32_i2c_v2.c
@@ -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)
diff --git a/arch/arm/src/stm32/stm32g4xxxx_rcc.c
b/arch/arm/src/stm32/stm32g4xxxx_rcc.c
index 790f30d162..bc1b6303b5 100644
--- a/arch/arm/src/stm32/stm32g4xxxx_rcc.c
+++ b/arch/arm/src/stm32/stm32g4xxxx_rcc.c
@@ -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)