This is an automated email from the ASF dual-hosted git repository.

linguini pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit afda7316e553ffdad50f639718bed54ee65e0a42
Author: raiden00pl <[email protected]>
AuthorDate: Sat Apr 11 11:51:28 2026 +0200

    arch/stm32f0l0g0/tim: TIM2 is 32-bit on F0/G0/C0
    
    fix TIM2 width - it is 32-bit on F0/G0/C0 but 16-bit on C0
    
    Signed-off-by: raiden00pl <[email protected]>
---
 arch/arm/src/stm32f0l0g0/hardware/stm32_tim.h | 22 ++++++++++++++++++
 arch/arm/src/stm32f0l0g0/stm32_tim.c          | 33 ++++++++++++++++++---------
 arch/arm/src/stm32f0l0g0/stm32_tim.h          |  2 ++
 3 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32_tim.h 
b/arch/arm/src/stm32f0l0g0/hardware/stm32_tim.h
index 7546bc72cd9..91fea96af14 100644
--- a/arch/arm/src/stm32f0l0g0/hardware/stm32_tim.h
+++ b/arch/arm/src/stm32f0l0g0/hardware/stm32_tim.h
@@ -23,10 +23,32 @@
 #ifndef __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32_TIM_H
 #define __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32_TIM_H
 
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include "chip.h"
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
+/* Timer Capabilities *******************************************************/
+
+/* TIM2 is 16-bit on STM32L0, but 32-bit on STM32F0, STM32G0 and STM32C0 */
+
+#if defined(CONFIG_ARCH_CHIP_STM32L0)
+#  define HAVE_TIM2_16BIT  1
+#  undef  HAVE_TIM2_32BIT
+#elif defined(CONFIG_ARCH_CHIP_STM32G0) || 
defined(CONFIG_STM32F0L0G0_STM32F09X)
+#  define HAVE_TIM2_32BIT  1
+#  undef  HAVE_TIM2_16BIT
+#else
+#  define HAVE_TIM2_32BIT  1
+#  undef  HAVE_TIM2_16BIT
+#endif
+
 /* TODO Missing TIM2 definitions available on STM32G0x1 */
 
 /* Register Offsets *********************************************************/
diff --git a/arch/arm/src/stm32f0l0g0/stm32_tim.c 
b/arch/arm/src/stm32f0l0g0/stm32_tim.c
index e1e70c7d1b9..f3c76fa97e2 100644
--- a/arch/arm/src/stm32f0l0g0/stm32_tim.c
+++ b/arch/arm/src/stm32f0l0g0/stm32_tim.c
@@ -284,6 +284,7 @@ static void stm32_tim_setperiod(struct stm32_tim_dev_s *dev,
                                 uint32_t period);
 static uint32_t stm32_tim_getperiod(struct stm32_tim_dev_s *dev);
 static uint32_t stm32_tim_getcounter(struct stm32_tim_dev_s *dev);
+static int  stm32_tim_getwidth(struct stm32_tim_dev_s *dev);
 static int  stm32_tim_setchannel(struct stm32_tim_dev_s *dev,
                                  uint8_t channel,
                                  stm32_tim_channel_t mode);
@@ -313,6 +314,7 @@ static const struct stm32_tim_ops_s stm32_tim_ops =
   .setperiod      = &stm32_tim_setperiod,
   .getperiod      = &stm32_tim_getperiod,
   .getcounter     = &stm32_tim_getcounter,
+  .getwidth       = &stm32_tim_getwidth,
   .setchannel     = &stm32_tim_setchannel,
   .setcompare     = &stm32_tim_setcompare,
   .getcapture     = &stm32_tim_getcapture,
@@ -749,21 +751,30 @@ static uint32_t stm32_tim_getperiod (struct 
stm32_tim_dev_s *dev)
   return stm32_getreg32 (dev, STM32_GTIM_ARR_OFFSET);
 }
 
-static uint32_t stm32_tim_getcounter(struct stm32_tim_dev_s *dev)
+static int stm32_tim_getwidth(struct stm32_tim_dev_s *dev)
 {
   DEBUGASSERT(dev != NULL);
-  /* According to STM32G0x0 datasheet, TIMx_CNT registers are 32-bits but
-   * CNT field is 16-bits [15:0].
-   * TIM 1, 3, 6-7, 14-17
-   */
 
-  /* In datasheet page 988, there is a useless bit named UIFCPY in TIMx_CNT.
-   * reset it it result when not TIM2 or TIM5.
-   */
+#ifdef HAVE_TIM2_32BIT
+  /* TIM2 is 16-bit on L0 */
+
+  if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM2_BASE)
+    {
+      return 32;
+    }
+#endif
 
-  uint32_t counter = stm32_getreg32(dev, STM32_GTIM_CNT_OFFSET);
-  counter &= 0xffff;
-  return counter;
+  /* All other timers are 16-bit */
+
+  return 16;
+}
+
+static uint32_t stm32_tim_getcounter(struct stm32_tim_dev_s *dev)
+{
+  DEBUGASSERT(dev != NULL);
+  return stm32_tim_getwidth(dev) > 16 ?
+    stm32_getreg32(dev, STM32_GTIM_CNT_OFFSET) :
+    (uint32_t)stm32_getreg16(dev, STM32_GTIM_CNT_OFFSET);
 }
 
 static int stm32_tim_setisr(struct stm32_tim_dev_s *dev,
diff --git a/arch/arm/src/stm32f0l0g0/stm32_tim.h 
b/arch/arm/src/stm32f0l0g0/stm32_tim.h
index 967abca2a28..ba9d7c7fbc4 100644
--- a/arch/arm/src/stm32f0l0g0/stm32_tim.h
+++ b/arch/arm/src/stm32f0l0g0/stm32_tim.h
@@ -58,6 +58,7 @@
 #define STM32_TIM_SETPERIOD(d,period)   ((d)->ops->setperiod(d,period))
 #define STM32_TIM_GETPERIOD(d)          ((d)->ops->getperiod(d))
 #define STM32_TIM_GETCOUNTER(d)         ((d)->ops->getcounter(d))
+#define STM32_TIM_GETWIDTH(d)           ((d)->ops->getwidth(d))
 #define STM32_TIM_SETCHANNEL(d,ch,mode) ((d)->ops->setchannel(d,ch,mode))
 #define STM32_TIM_SETCOMPARE(d,ch,comp) ((d)->ops->setcompare(d,ch,comp))
 #define STM32_TIM_GETCAPTURE(d,ch)      ((d)->ops->getcapture(d,ch))
@@ -170,6 +171,7 @@ struct stm32_tim_ops_s
   void (*setperiod)(struct stm32_tim_dev_s *dev, uint32_t period);
   uint32_t (*getperiod)(struct stm32_tim_dev_s *dev);
   uint32_t (*getcounter)(struct stm32_tim_dev_s *dev);
+  int  (*getwidth)(struct stm32_tim_dev_s *dev);
 
   /* General and Advanced Timers Adds */
 

Reply via email to