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)

Reply via email to