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

xiaoxiang781216 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 d5b78ed9aa6 arch/arm/src/stm32: unify pulse count driver into 
common/stm32
d5b78ed9aa6 is described below

commit d5b78ed9aa630fd97bf5c804ddd3e1ae36acccfb
Author: raiden00pl <[email protected]>
AuthorDate: Wed Jun 3 12:29:40 2026 +0200

    arch/arm/src/stm32: unify pulse count driver into common/stm32
    
    Merge the six near-identical pulse count drivers (two common, plus
    the F7/H7/H5/L4 copies) into a single common/stm32/stm32_pulsecount.c.
    
    Signed-off-by: raiden00pl <[email protected]>
---
 .github/CODEOWNERS                                 |    3 +-
 Documentation/guides/stm32_ports.rst               |   32 +-
 arch/arm/src/common/stm32/CMakeLists.txt           |   12 +-
 arch/arm/src/common/stm32/Kconfig.tim              |    3 -
 arch/arm/src/common/stm32/Make.defs                |   14 +-
 .../{stm32f7 => common/stm32}/stm32_pulsecount.c   |   62 +-
 .../common/stm32/stm32_pulsecount_m3m4_v1v2v3.c    | 1775 --------------------
 arch/arm/src/stm32c0/stm32.h                       |    1 +
 arch/arm/src/stm32f0/stm32.h                       |    1 +
 arch/arm/src/stm32f7/CMakeLists.txt                |    4 -
 arch/arm/src/stm32f7/Make.defs                     |    4 -
 arch/arm/src/stm32f7/stm32_pulsecount.h            |   39 -
 arch/arm/src/stm32g0/stm32.h                       |    1 +
 arch/arm/src/stm32h5/CMakeLists.txt                |    4 -
 arch/arm/src/stm32h5/Make.defs                     |    4 -
 arch/arm/src/stm32h5/stm32.h                       |    1 +
 arch/arm/src/stm32h5/stm32_pulsecount.h            |   39 -
 arch/arm/src/stm32h7/CMakeLists.txt                |    4 -
 arch/arm/src/stm32h7/Make.defs                     |    4 -
 arch/arm/src/stm32h7/stm32.h                       |    1 +
 arch/arm/src/stm32h7/stm32_pulsecount.h            |   39 -
 arch/arm/src/stm32l0/stm32.h                       |    1 +
 arch/arm/src/stm32l4/CMakeLists.txt                |    4 -
 arch/arm/src/stm32l4/Make.defs                     |    4 -
 arch/arm/src/stm32l4/stm32l4_pulsecount.h          |   39 -
 25 files changed, 83 insertions(+), 2012 deletions(-)

diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 3528e51466d..6389d90e480 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1820,9 +1820,8 @@ arch/arm/src/common/stm32/stm32_pminitialize_m3m4_v1.c 
[email protected] ju
 arch/arm/src/common/stm32/stm32_pmsleep_m3m4_v1.c [email protected] 
[email protected] [email protected] 
[email protected] [email protected]
 arch/arm/src/common/stm32/stm32_pmstandby_m3m4_v1.c [email protected] 
[email protected] [email protected] 
[email protected]
 arch/arm/src/common/stm32/stm32_pmstop_m3m4_v1.c [email protected] 
[email protected] [email protected]
+arch/arm/src/common/stm32/stm32_pulsecount.c [email protected]
 arch/arm/src/common/stm32/stm32_pulsecount.h [email protected] 
[email protected] [email protected] [email protected]
-arch/arm/src/common/stm32/stm32_pulsecount_m0_v1.c [email protected]
-arch/arm/src/common/stm32/stm32_pulsecount_m3m4_v1v2v3.c [email protected]
 arch/arm/src/common/stm32/stm32_pwm.h [email protected] [email protected]
 arch/arm/src/common/stm32/stm32_pwm_m0_v1.c [email protected] 
[email protected] [email protected] [email protected] [email protected]
 arch/arm/src/common/stm32/stm32_pwm_m0_v1.h [email protected] 
[email protected] [email protected] [email protected] [email protected]
diff --git a/Documentation/guides/stm32_ports.rst 
b/Documentation/guides/stm32_ports.rst
index 50abdfe7cdd..70d0d207e72 100644
--- a/Documentation/guides/stm32_ports.rst
+++ b/Documentation/guides/stm32_ports.rst
@@ -418,9 +418,9 @@ WWDG          v1            
arch/arm/src/common/stm32/stm32_wwdg_m3m4_v1.c
 STM32L4
 -------
 
-============  ============  =========================================
+============  ============  ============================================
 Peripheral    Core version  Driver                                   
-============  ============  =========================================
+============  ============  ============================================
 ADC           to be done    arch/arm/src/stm32l4/stm32l4_adc.c       
 CAN/FDCAN     bxCAN         arch/arm/src/stm32l4/stm32l4_can.c       
 COMP          to be done    arch/arm/src/stm32l4/stm32l4_comp.c      
@@ -444,18 +444,18 @@ SPI/I2S       to be done    
arch/arm/src/stm32l4/stm32l4_spi.c
 TIM           to be done    arch/arm/src/stm32l4/stm32l4_tim.c       
 USART/LPUART  v3            arch/arm/src/stm32l4/stm32l4_serial.c    
 USB           OTG FS        arch/arm/src/stm32l4/stm32l4_otgfsdev.c  
-PULSECOUNT    n/a           arch/arm/src/stm32l4/stm32l4_pulsecount.c
+PULSECOUNT    n/a           arch/arm/src/common/stm32/stm32_pulsecount.c
 PWM           n/a           arch/arm/src/stm32l4/stm32l4_pwm.c       
 QENCODER      n/a           arch/arm/src/stm32l4/stm32l4_qencoder.c  
 USB host      n/a           arch/arm/src/stm32l4/stm32l4_otgfshost.c 
-============  ============  =========================================
+============  ============  ============================================
 
 STM32F7
 -------
 
-============  ============  =======================================
+============  ============  ============================================
 Peripheral    Core version  Driver                                 
-============  ============  =======================================
+============  ============  ============================================
 ADC           to be done    arch/arm/src/stm32f7/stm32_adc.c       
 CAN/FDCAN     bxCAN         arch/arm/src/stm32f7/stm32_can.c       
 DAC           to be done    not supported                          
@@ -483,12 +483,12 @@ WWDG          v1            not supported
 BBSRAM        n/a           arch/arm/src/stm32f7/stm32_bbsram.c    
 CAPTURE       n/a           arch/arm/src/stm32f7/stm32_capture.c   
 FOC           n/a           arch/arm/src/stm32f7/stm32_foc.c       
-PULSECOUNT    n/a           arch/arm/src/stm32f7/stm32_pulsecount.c
+PULSECOUNT    n/a           arch/arm/src/common/stm32/stm32_pulsecount.c
 PWM           n/a           arch/arm/src/stm32f7/stm32_pwm.c       
 QENCODER      n/a           arch/arm/src/stm32f7/stm32_qencoder.c  
 SAI           n/a           arch/arm/src/stm32f7/stm32_sai.c       
 USB host      n/a           arch/arm/src/stm32f7/stm32_otghost.c   
-============  ============  =======================================
+============  ============  ============================================
 
 STM32G0
 -------
@@ -522,9 +522,9 @@ WWDG          v1            
arch/arm/src/common/stm32/stm32_wwdg_m0_v1.c
 STM32H5
 -------
 
-============  ============  =======================================
+============  ============  ============================================
 Peripheral    Core version  Driver                                 
-============  ============  =======================================
+============  ============  ============================================
 ADC           to be done    arch/arm/src/stm32h5/stm32_adc.c       
 AES/CRYP      to be done    not supported                          
 CAN/FDCAN     FDCAN         arch/arm/src/stm32h5/stm32_fdcan.c     
@@ -544,18 +544,18 @@ SPI/I2S       to be done    
arch/arm/src/stm32h5/stm32_spi.c
 TIM           to be done    arch/arm/src/stm32h5/stm32_tim.c       
 USART/LPUART  v3            arch/arm/src/stm32h5/stm32_serial.c    
 USB           FS            arch/arm/src/stm32h5/stm32_usbfs.c     
-PULSECOUNT    n/a           arch/arm/src/stm32h5/stm32_pulsecount.c
+PULSECOUNT    n/a           arch/arm/src/common/stm32/stm32_pulsecount.c
 PWM           n/a           arch/arm/src/stm32h5/stm32_pwm.c       
 RNG           n/a           arch/arm/src/stm32h5/stm32_rng.c       
 USB host      n/a           arch/arm/src/stm32h5/stm32_usbdrdhost.c
-============  ============  =======================================
+============  ============  ============================================
 
 STM32H7
 -------
 
-============  ============  =======================================
+============  ============  ============================================
 Peripheral    Core version  Driver                                 
-============  ============  =======================================
+============  ============  ============================================
 ADC           to be done    arch/arm/src/stm32h7/stm32_adc.c       
 BDMA          to be done    arch/arm/src/stm32h7/stm32_dma.c       
 CAN/FDCAN     FDCAN         arch/arm/src/stm32h7/stm32_fdcan_sock.c
@@ -587,11 +587,11 @@ AES/CRYP      n/a           
arch/arm/src/stm32h7/stm32_aes.c
 BBSRAM        n/a           arch/arm/src/stm32h7/stm32_bbsram.c    
 CAPTURE       n/a           arch/arm/src/stm32h7/stm32_capture.c   
 LPTIM         n/a           arch/arm/src/stm32h7/stm32_lptim.c     
-PULSECOUNT    n/a           arch/arm/src/stm32h7/stm32_pulsecount.c
+PULSECOUNT    n/a           arch/arm/src/common/stm32/stm32_pulsecount.c
 PWM           n/a           arch/arm/src/stm32h7/stm32_pwm.c       
 QENCODER      n/a           arch/arm/src/stm32h7/stm32_qencoder.c  
 USB host      n/a           arch/arm/src/stm32h7/stm32_otghost.c   
-============  ============  =======================================
+============  ============  ============================================
 
 STM32L0
 -------
diff --git a/arch/arm/src/common/stm32/CMakeLists.txt 
b/arch/arm/src/common/stm32/CMakeLists.txt
index 5499cbcf4b9..c2299ee530a 100644
--- a/arch/arm/src/common/stm32/CMakeLists.txt
+++ b/arch/arm/src/common/stm32/CMakeLists.txt
@@ -34,6 +34,10 @@ set(SRCS)
 list(APPEND SRCS stm32_waste.c)
 list(APPEND SRCS stm32_uid.c)
 
+if(CONFIG_STM32_PULSECOUNT)
+  list(APPEND SRCS stm32_pulsecount.c)
+endif()
+
 if(CONFIG_STM32_COMMON_LEGACY)
   list(
     APPEND
@@ -281,10 +285,6 @@ if(CONFIG_STM32_COMMON_LEGACY)
     list(APPEND SRCS stm32_pwm_m3m4_v1v2v3.c)
   endif()
 
-  if(CONFIG_STM32_PULSECOUNT)
-    list(APPEND SRCS stm32_pulsecount_m3m4_v1v2v3.c)
-  endif()
-
   if(CONFIG_STM32_CAP)
     list(APPEND SRCS stm32_capture_m3m4_v1_lowerhalf.c)
   endif()
@@ -444,10 +444,6 @@ if(CONFIG_ARCH_CORTEXM0)
     list(APPEND SRCS stm32_pwm_m0_v1.c)
   endif()
 
-  if(CONFIG_PULSECOUNT AND CONFIG_STM32_TIM1_PULSECOUNT)
-    list(APPEND SRCS stm32_pulsecount_m0_v1.c)
-  endif()
-
   if(CONFIG_STM32_ADC AND CONFIG_STM32_HAVE_IP_ADC_M0_V1)
     list(APPEND SRCS stm32_adc_m0_v1.c)
   endif()
diff --git a/arch/arm/src/common/stm32/Kconfig.tim 
b/arch/arm/src/common/stm32/Kconfig.tim
index 76b4b527648..b8e7852a920 100644
--- a/arch/arm/src/common/stm32/Kconfig.tim
+++ b/arch/arm/src/common/stm32/Kconfig.tim
@@ -2762,7 +2762,6 @@ config STM32_TIM1_PULSECOUNT_TDTS
        int "TIM1 pulse count clock division"
        default 0
        range 0 2
-       depends on !STM32_HAVE_IP_TIMERS
 
 config STM32_TIM1_PULSECOUNT_CHANNEL
        int "TIM1 pulse count channel"
@@ -2775,13 +2774,11 @@ config STM32_TIM1_PULSECOUNT_POL
        int "TIM1 pulse count output polarity"
        default 0
        range 0 1
-       depends on !STM32_HAVE_IP_TIMERS
 
 config STM32_TIM1_PULSECOUNT_IDLE
        int "TIM1 pulse count idle state"
        default 0
        range 0 1
-       depends on !STM32_HAVE_IP_TIMERS
 
 endif # STM32_TIM1_PULSECOUNT
 
diff --git a/arch/arm/src/common/stm32/Make.defs 
b/arch/arm/src/common/stm32/Make.defs
index ffb46e0a089..686a84e4d73 100644
--- a/arch/arm/src/common/stm32/Make.defs
+++ b/arch/arm/src/common/stm32/Make.defs
@@ -42,6 +42,10 @@ ARCHXXINCLUDES += ${INCDIR_PREFIX}$(STM32_COMMON_SRCDIR)
 CHIP_CSRCS += stm32_waste.c
 CHIP_CSRCS += stm32_uid.c
 
+ifeq ($(CONFIG_STM32_PULSECOUNT),y)
+CHIP_CSRCS += stm32_pulsecount.c
+endif
+
 ifeq ($(CONFIG_STM32_COMMON_LEGACY),y)
 
 CHIP_CSRCS += stm32_allocateheap_m3m4_v1.c
@@ -314,10 +318,6 @@ ifeq ($(CONFIG_STM32_PWM),y)
 CHIP_CSRCS += stm32_pwm_m3m4_v1v2v3.c
 endif
 
-ifeq ($(CONFIG_STM32_PULSECOUNT),y)
-CHIP_CSRCS += stm32_pulsecount_m3m4_v1v2v3.c
-endif
-
 ifeq ($(CONFIG_STM32_CAP),y)
 CHIP_CSRCS += stm32_capture_m3m4_v1_lowerhalf.c
 endif
@@ -495,12 +495,6 @@ ifeq ($(CONFIG_STM32_PWM),y)
 CHIP_CSRCS += stm32_pwm_m0_v1.c
 endif
 
-ifeq ($(CONFIG_PULSECOUNT),y)
-ifeq ($(CONFIG_STM32_TIM1_PULSECOUNT),y)
-CHIP_CSRCS += stm32_pulsecount_m0_v1.c
-endif
-endif
-
 ifeq ($(CONFIG_STM32_ADC)$(CONFIG_STM32_HAVE_IP_ADC_M0_V1),yy)
 CHIP_CSRCS += stm32_adc_m0_v1.c
 endif
diff --git a/arch/arm/src/stm32f7/stm32_pulsecount.c 
b/arch/arm/src/common/stm32/stm32_pulsecount.c
similarity index 96%
rename from arch/arm/src/stm32f7/stm32_pulsecount.c
rename to arch/arm/src/common/stm32/stm32_pulsecount.c
index 457f9e955c0..0927f3c4ee7 100644
--- a/arch/arm/src/stm32f7/stm32_pulsecount.c
+++ b/arch/arm/src/common/stm32/stm32_pulsecount.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/src/stm32f7/stm32_pulsecount.c
+ * arch/arm/src/common/stm32/stm32_pulsecount.c
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -39,9 +39,9 @@
 #include "arm_internal.h"
 #include "chip.h"
 #include "stm32_pulsecount.h"
-#include "stm32_rcc.h"
-#include "stm32_gpio.h"
-#include "stm32_tim.h"
+#include "stm32.h"
+
+/* Generalized pulse count support for all STM32 families */
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -70,9 +70,31 @@
 #define TIMRCCRST_TIM8   STM32_RCC_APB2RSTR
 #define TIMRST_TIM8      RCC_APB2RSTR_TIM8RST
 
+/* The TIM1/TIM8 update-event interrupt vector is named differently across
+ * families. This will be unified later.
+ */
+
+#if defined(STM32_IRQ_TIM1UP)
+#  define PULSECOUNT_TIM1_IRQ  STM32_IRQ_TIM1UP
+#elif defined(STM32_IRQ_TIM1_UP)
+#  define PULSECOUNT_TIM1_IRQ  STM32_IRQ_TIM1_UP
+#elif defined(STM32_IRQ_TIM1_BRK)
+#  define PULSECOUNT_TIM1_IRQ  STM32_IRQ_TIM1_BRK
+#endif
+
+#if defined(STM32_IRQ_TIM8UP)
+#  define PULSECOUNT_TIM8_IRQ  STM32_IRQ_TIM8UP
+#elif defined(STM32_IRQ_TIM8_UP)
+#  define PULSECOUNT_TIM8_IRQ  STM32_IRQ_TIM8_UP
+#endif
+
 /* Default GPIO pins state */
 
-#define PINCFG_DEFAULT (GPIO_INPUT | GPIO_FLOAT)
+#if defined(CONFIG_STM32_STM32F10XX)
+#  define PINCFG_DEFAULT (GPIO_INPUT | GPIO_CNF_INFLOAT | GPIO_MODE_INPUT)
+#else
+#  define PINCFG_DEFAULT (GPIO_INPUT | GPIO_FLOAT)
+#endif
 
 #define PULSECOUNT_POL_NEG      1
 #define PULSECOUNT_IDLE_ACTIVE  1
@@ -247,7 +269,7 @@ static struct stm32_tim_s g_pulsecount1dev =
   .timid       = 1,
   .timtype     = TIMTYPE_TIM1,
   .t_dts       = CONFIG_STM32_TIM1_PULSECOUNT_TDTS,
-  .irq         = STM32_IRQ_TIM1UP,
+  .irq         = PULSECOUNT_TIM1_IRQ,
   .base        = STM32_TIM1_BASE,
   .pclk        = TIMCLK_TIM1,
 };
@@ -298,7 +320,7 @@ static struct stm32_tim_s g_pulsecount8dev =
   .timid       = 8,
   .timtype     = TIMTYPE_TIM8,
   .t_dts       = CONFIG_STM32_TIM8_PULSECOUNT_TDTS,
-  .irq         = STM32_IRQ_TIM8UP,
+  .irq         = PULSECOUNT_TIM8_IRQ,
   .base        = STM32_TIM8_BASE,
   .pclk        = TIMCLK_TIM8,
 };
@@ -342,6 +364,11 @@ static bool pulsecount_reg_is_32bit(uint8_t timtype, 
uint32_t offset)
 {
   bool ret = false;
 
+  /* TODO: If all the advanced-timer registers are safely word-accessible
+   * then this helper could be dropped and every access made 32-bit.
+   * This is NOT verified yet.
+   */
+
   if (timtype == TIMTYPE_ADVANCED)
     {
       if (offset == STM32_ATIM_CR2_OFFSET ||
@@ -807,10 +834,17 @@ static int pulsecount_channel_configure(struct 
pulsecount_lowerhalf_s *dev,
       case 3:
         {
           ccmr &= ~(ATIM_CCMR1_CC1S_MASK | ATIM_CCMR1_OC1M_MASK |
-                    ATIM_CCMR1_OC1PE | ATIM_CCMR1_OC1M);
+                     ATIM_CCMR1_OC1PE);
           ocmode |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC1S_SHIFT);
           ocmode |= (chanmode << ATIM_CCMR1_OC1M_SHIFT);
           ocmode |= ATIM_CCMR1_OC1PE;
+#ifdef ATIM_CCMR1_OC1M
+          /* Clear the extended (bit 3) output-compare-mode bit on the timer
+           * IP versions that have it.
+           */
+
+          ccmr &= ~(ATIM_CCMR1_OC1M);
+#endif
           break;
         }
 
@@ -820,10 +854,17 @@ static int pulsecount_channel_configure(struct 
pulsecount_lowerhalf_s *dev,
       case 4:
         {
           ccmr &= ~(ATIM_CCMR1_CC2S_MASK | ATIM_CCMR1_OC2M_MASK |
-                    ATIM_CCMR1_OC2PE | ATIM_CCMR1_OC2M);
+                     ATIM_CCMR1_OC2PE);
           ocmode |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC2S_SHIFT);
           ocmode |= (chanmode << ATIM_CCMR1_OC2M_SHIFT);
           ocmode |= ATIM_CCMR1_OC2PE;
+#ifdef ATIM_CCMR1_OC2M
+          /* Clear the extended (bit 3) output-compare-mode bit on the timer
+           * IP versions that have it.
+           */
+
+          ccmr &= ~(ATIM_CCMR1_OC2M);
+#endif
           break;
         }
     }
@@ -1672,7 +1713,8 @@ static int pulsecount_start(struct pulsecount_lowerhalf_s 
*dev,
 
   if (info->count > 0)
     {
-      /* Only the advanced timers (TIM1,8 can support the pulse counting) */
+      /* Only the advanced timers (TIM1,8 can support the pulse counting)
+       */
 
       if (priv->timtype != TIMTYPE_ADVANCED)
         {
diff --git a/arch/arm/src/common/stm32/stm32_pulsecount_m3m4_v1v2v3.c 
b/arch/arm/src/common/stm32/stm32_pulsecount_m3m4_v1v2v3.c
deleted file mode 100644
index 099240622c5..00000000000
--- a/arch/arm/src/common/stm32/stm32_pulsecount_m3m4_v1v2v3.c
+++ /dev/null
@@ -1,1775 +0,0 @@
-/****************************************************************************
- * arch/arm/src/common/stm32/stm32_pulsecount_m3m4_v1v2v3.c
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <assert.h>
-#include <errno.h>
-#include <nuttx/debug.h>
-
-#include <nuttx/arch.h>
-#include <arch/board/board.h>
-
-#include "arm_internal.h"
-#include "chip.h"
-#include "stm32_pulsecount.h"
-#include "stm32_rcc.h"
-#include "stm32_gpio.h"
-#include "stm32_tim.h"
-
-/* This module then only compiles if there is at least one enabled timer
- * intended for use with the pulsecount upper half driver.
- *
- * It implements support for both:
- *   1. STM32 TIMER IP version 1 - F0, F1, F2, F37x, F4, L0, L1
- *   2. STM32 TIMER IP version 2 - F3 (no F37x), F7, H7, L4, L4+
- */
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Timer Definitions ********************************************************/
-
-/* Pulsecount is supported by advanced timers only. */
-
-#define TIMTYPE_ADVANCED  5
-#define TIMTYPE_TIM1      TIMTYPE_ADVANCED
-#define TIMTYPE_TIM8      TIMTYPE_ADVANCED
-
-/* Advanced timer clock source, RCC EN offset, enable bit,
- * RCC RST offset, reset bit to use
- */
-
-#  define TIMCLK_TIM1      STM32_TIM1_CLKIN
-#  define TIMRCCEN_TIM1    STM32_RCC_APB2ENR
-#  define TIMEN_TIM1       RCC_APB2ENR_TIM1EN
-#  define TIMRCCRST_TIM1   STM32_RCC_APB2RSTR
-#  define TIMRST_TIM1      RCC_APB2RSTR_TIM1RST
-#  define TIMCLK_TIM8      STM32_TIM8_CLKIN
-#  define TIMRCCEN_TIM8    STM32_RCC_APB2ENR
-#  define TIMEN_TIM8       RCC_APB2ENR_TIM8EN
-#  define TIMRCCRST_TIM8   STM32_RCC_APB2RSTR
-#  define TIMRST_TIM8      RCC_APB2RSTR_TIM8RST
-
-/* Default GPIO pins state */
-
-#if defined(CONFIG_STM32_STM32F10XX)
-#  define PINCFG_DEFAULT (GPIO_INPUT | GPIO_CNF_INFLOAT | GPIO_MODE_INPUT)
-#elif defined(CONFIG_STM32_STM32F20XX) ||         \
-    defined(CONFIG_STM32_STM32F30XX) ||           \
-    defined(CONFIG_STM32_STM32F33XX) ||           \
-    defined(CONFIG_STM32_STM32F37XX) ||           \
-    defined(CONFIG_STM32_STM32F4XXX) ||           \
-    defined(CONFIG_STM32_STM32L15XX) ||           \
-    defined(CONFIG_STM32_STM32G4XXX)
-#  define PINCFG_DEFAULT (GPIO_INPUT | GPIO_FLOAT)
-#else
-#  error "Unrecognized STM32 chip"
-#endif
-
-#define PULSECOUNT_POL_NEG      1
-#define PULSECOUNT_IDLE_ACTIVE  1
-
-/* Debug ********************************************************************/
-
-#ifdef CONFIG_DEBUG_TIMER_INFO
-#  define pulsecount_dumpgpio(p,m) stm32_dumpgpio(p,m)
-#else
-#  define pulsecount_dumpgpio(p,m)
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* Pulsecount output configuration */
-
-struct stm32_out_s
-{
-  uint8_t  in_use:1;
-  uint8_t  pol:1;
-  uint8_t  idle:1;
-  uint8_t  _res:5;
-  uint32_t pincfg;
-};
-
-/* Pulsecount channel configuration */
-
-struct stm32_chan_s
-{
-  uint8_t            channel;
-  struct stm32_out_s out1;
-};
-
-/* This structure represents the state of one pulsecount timer */
-
-struct stm32_tim_s
-{
-  struct stm32_chan_s  channel;
-  uint8_t              timid:5;
-  uint8_t              timtype:3;
-  uint8_t              t_dts:3;
-  uint8_t              _res:5;
-  uint8_t              irq;
-  uint8_t              prev;
-  uint8_t              curr;
-  uint32_t             count;
-  uint32_t             frequency;
-  uint32_t             base;
-  uint32_t             pclk;
-  void                *handle;
-};
-
-struct stm32_pulsecount_s
-{
-  const struct pulsecount_ops_s *ops;
-  struct stm32_tim_s *timer;
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Register access */
-
-static uint32_t pulsecount_getreg(struct stm32_tim_s *priv, int offset);
-static void pulsecount_putreg(struct stm32_tim_s *priv, int offset,
-                              uint32_t value);
-static void pulsecount_modifyreg(struct stm32_tim_s *priv, uint32_t offset,
-                                 uint32_t clearbits, uint32_t setbits);
-
-#ifdef CONFIG_DEBUG_TIMER_INFO
-static void pulsecount_dumpregs(struct pulsecount_lowerhalf_s *dev,
-                                const char *msg);
-#else
-#  define pulsecount_dumpregs(priv,msg)
-#endif
-
-/* Timer management */
-
-static int pulsecount_ccr_update(struct pulsecount_lowerhalf_s *dev,
-                                 uint8_t index, uint32_t ccr);
-static int pulsecount_duty_update(struct pulsecount_lowerhalf_s *dev,
-                                  uint8_t channel, ub16_t duty);
-static int pulsecount_frequency_update(struct pulsecount_lowerhalf_s *dev,
-                                       uint32_t frequency);
-static int pulsecount_timer_configure(struct stm32_tim_s *priv);
-static int pulsecount_channel_configure(struct pulsecount_lowerhalf_s *dev,
-                                        uint8_t channel);
-static int pulsecount_output_configure(struct stm32_tim_s *priv,
-                                       struct stm32_chan_s *chan);
-static int pulsecount_outputs_enable(struct pulsecount_lowerhalf_s *dev,
-                                     uint16_t outputs, bool state);
-static void pulsecount_moe_enable(struct pulsecount_lowerhalf_s *dev,
-                                  bool enable);
-static int pulsecount_configure(struct pulsecount_lowerhalf_s *dev);
-static int pulsecount_timer(struct pulsecount_lowerhalf_s *dev,
-                            const struct pulsecount_info_s *info);
-static int pulsecount_interrupt(struct pulsecount_lowerhalf_s *dev);
-#  ifdef CONFIG_STM32_TIM1_PULSECOUNT
-static int pulsecount_tim1interrupt(int irq, void *context, void *arg);
-#  endif
-#  ifdef CONFIG_STM32_TIM8_PULSECOUNT
-static int pulsecount_tim8interrupt(int irq, void *context, void *arg);
-#  endif
-static uint8_t pulsecount_count(uint32_t count);
-
-/* Pulsecount driver methods */
-
-static int pulsecount_ll_setup(struct pulsecount_lowerhalf_s *dev);
-static int pulsecount_ll_shutdown(struct pulsecount_lowerhalf_s *dev);
-
-static int pulsecount_ll_stop(struct pulsecount_lowerhalf_s *dev);
-static int pulsecount_ll_ioctl(struct pulsecount_lowerhalf_s *dev,
-                               int cmd, unsigned long arg);
-
-static int pulsecount_setup(struct pulsecount_lowerhalf_s *dev);
-static int pulsecount_shutdown(struct pulsecount_lowerhalf_s *dev);
-static int pulsecount_start(struct pulsecount_lowerhalf_s *dev,
-                            const struct pulsecount_info_s *info,
-                            void *handle);
-static int pulsecount_stop(struct pulsecount_lowerhalf_s *dev);
-static int pulsecount_ioctl(struct pulsecount_lowerhalf_s *dev,
-                            int cmd, unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-#ifdef CONFIG_STM32_TIM1_PULSECOUNT
-
-static struct stm32_tim_s g_pulsecount1dev =
-{
-  .channel =
-  {
-    .channel = CONFIG_STM32_TIM1_PULSECOUNT_CHANNEL,
-#if CONFIG_STM32_TIM1_PULSECOUNT_CHANNEL == 1
-    .out1 =
-    {
-      .in_use  = 1,
-      .pol     = CONFIG_STM32_TIM1_PULSECOUNT_POL,
-      .idle    = CONFIG_STM32_TIM1_PULSECOUNT_IDLE,
-      .pincfg  = GPIO_TIM1_CH1OUT,
-    },
-#elif CONFIG_STM32_TIM1_PULSECOUNT_CHANNEL == 2
-    .out1 =
-    {
-      .in_use  = 1,
-      .pol     = CONFIG_STM32_TIM1_PULSECOUNT_POL,
-      .idle    = CONFIG_STM32_TIM1_PULSECOUNT_IDLE,
-      .pincfg  = GPIO_TIM1_CH2OUT,
-    },
-#elif CONFIG_STM32_TIM1_PULSECOUNT_CHANNEL == 3
-    .out1 =
-    {
-      .in_use  = 1,
-      .pol     = CONFIG_STM32_TIM1_PULSECOUNT_POL,
-      .idle    = CONFIG_STM32_TIM1_PULSECOUNT_IDLE,
-      .pincfg  = GPIO_TIM1_CH3OUT,
-    },
-#elif CONFIG_STM32_TIM1_PULSECOUNT_CHANNEL == 4
-    .out1 =
-    {
-      .in_use  = 1,
-      .pol     = CONFIG_STM32_TIM1_PULSECOUNT_POL,
-      .idle    = CONFIG_STM32_TIM1_PULSECOUNT_IDLE,
-      .pincfg  = GPIO_TIM1_CH4OUT,
-    },
-#endif
-  },
-  .timid       = 1,
-  .timtype     = TIMTYPE_TIM1,
-  .t_dts       = CONFIG_STM32_TIM1_PULSECOUNT_TDTS,
-  .irq         = STM32_IRQ_TIM1UP,
-  .base        = STM32_TIM1_BASE,
-  .pclk        = TIMCLK_TIM1,
-};
-
-#endif /* CONFIG_STM32_TIM1_PULSECOUNT */
-
-#ifdef CONFIG_STM32_TIM8_PULSECOUNT
-
-static struct stm32_tim_s g_pulsecount8dev =
-{
-  .channel =
-  {
-    .channel = CONFIG_STM32_TIM8_PULSECOUNT_CHANNEL,
-#if CONFIG_STM32_TIM8_PULSECOUNT_CHANNEL == 1
-    .out1 =
-    {
-      .in_use  = 1,
-      .pol     = CONFIG_STM32_TIM8_PULSECOUNT_POL,
-      .idle    = CONFIG_STM32_TIM8_PULSECOUNT_IDLE,
-      .pincfg  = GPIO_TIM8_CH1OUT,
-    },
-#elif CONFIG_STM32_TIM8_PULSECOUNT_CHANNEL == 2
-    .out1 =
-    {
-      .in_use  = 1,
-      .pol     = CONFIG_STM32_TIM8_PULSECOUNT_POL,
-      .idle    = CONFIG_STM32_TIM8_PULSECOUNT_IDLE,
-      .pincfg  = GPIO_TIM8_CH2OUT,
-    },
-#elif CONFIG_STM32_TIM8_PULSECOUNT_CHANNEL == 3
-    .out1 =
-    {
-      .in_use  = 1,
-      .pol     = CONFIG_STM32_TIM8_PULSECOUNT_POL,
-      .idle    = CONFIG_STM32_TIM8_PULSECOUNT_IDLE,
-      .pincfg  = GPIO_TIM8_CH3OUT,
-    },
-#elif CONFIG_STM32_TIM8_PULSECOUNT_CHANNEL == 4
-    .out1 =
-    {
-      .in_use  = 1,
-      .pol     = CONFIG_STM32_TIM8_PULSECOUNT_POL,
-      .idle    = CONFIG_STM32_TIM8_PULSECOUNT_IDLE,
-      .pincfg  = GPIO_TIM8_CH4OUT,
-    },
-#endif
-  },
-  .timid       = 8,
-  .timtype     = TIMTYPE_TIM8,
-  .t_dts       = CONFIG_STM32_TIM8_PULSECOUNT_TDTS,
-  .irq         = STM32_IRQ_TIM8UP,
-  .base        = STM32_TIM8_BASE,
-  .pclk        = TIMCLK_TIM8,
-};
-
-#endif /* CONFIG_STM32_TIM8_PULSECOUNT */
-
-static const struct pulsecount_ops_s g_pulsecountops =
-{
-  .setup       = pulsecount_setup,
-  .shutdown    = pulsecount_shutdown,
-  .start       = pulsecount_start,
-  .stop        = pulsecount_stop,
-  .ioctl       = pulsecount_ioctl,
-};
-
-#ifdef CONFIG_STM32_TIM1_PULSECOUNT
-static struct stm32_pulsecount_s g_pulsecount1lower =
-{
-  .ops = &g_pulsecountops,
-  .timer = &g_pulsecount1dev,
-};
-#endif
-
-#ifdef CONFIG_STM32_TIM8_PULSECOUNT
-static struct stm32_pulsecount_s g_pulsecount8lower =
-{
-  .ops = &g_pulsecountops,
-  .timer = &g_pulsecount8dev,
-};
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pulsecount_reg_is_32bit
- ****************************************************************************/
-
-static bool pulsecount_reg_is_32bit(uint8_t timtype, uint32_t offset)
-{
-  bool ret = false;
-
-  if (timtype == TIMTYPE_ADVANCED)
-    {
-      if (offset == STM32_ATIM_CR2_OFFSET ||
-          offset == STM32_ATIM_CCMR1_OFFSET ||
-          offset == STM32_ATIM_CCMR2_OFFSET ||
-          offset == STM32_ATIM_CCER_OFFSET ||
-          offset == STM32_ATIM_BDTR_OFFSET)
-        {
-          ret = true;
-        }
-    }
-
-  return ret;
-}
-
-/****************************************************************************
- * Name: pulsecount_getreg
- *
- * Description:
- *   Read the value of an pulsecount timer register
- *
- * Input Parameters:
- *   priv   - A reference to the pulsecount block status
- *   offset - The offset to the register to read
- *
- * Returned Value:
- *   The current contents of the specified register
- *
- ****************************************************************************/
-
-static uint32_t pulsecount_getreg(struct stm32_tim_s *priv, int offset)
-{
-  uint32_t retval = 0;
-
-  if (pulsecount_reg_is_32bit(priv->timtype, offset) == true)
-    {
-      /* 32-bit register */
-
-      retval = getreg32(priv->base + offset);
-    }
-  else
-    {
-      /* 16-bit register */
-
-      retval = getreg16(priv->base + offset);
-    }
-
-  /* Return 32-bit value */
-
-  return retval;
-}
-
-/****************************************************************************
- * Name: pulsecount_putreg
- *
- * Description:
- *   Read the value of an pulsecount timer register
- *
- * Input Parameters:
- *   priv   - A reference to the pulsecount block status
- *   offset - The offset to the register to read
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
-
-static void pulsecount_putreg(struct stm32_tim_s *priv, int offset,
-                              uint32_t value)
-{
-  if (pulsecount_reg_is_32bit(priv->timtype, offset) == true)
-    {
-      /* 32-bit register */
-
-      putreg32(value, priv->base + offset);
-    }
-  else
-    {
-      /* 16-bit register */
-
-      putreg16((uint16_t)value, priv->base + offset);
-    }
-}
-
-/****************************************************************************
- * Name: pulsecount_modifyreg
- *
- * Description:
- *   Modify timer register (32-bit or 16-bit)
- *
- * Input Parameters:
- *   priv    - A reference to the pulsecount block status
- *   offset  - The offset to the register to read
- *   clrbits - The bits to clear
- *   setbits - The bits to set
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
-
-static void pulsecount_modifyreg(struct stm32_tim_s *priv, uint32_t offset,
-                                 uint32_t clearbits, uint32_t setbits)
-{
-  if (pulsecount_reg_is_32bit(priv->timtype, offset) == true)
-    {
-      /* 32-bit register */
-
-      modifyreg32(priv->base + offset, clearbits, setbits);
-    }
-  else
-    {
-      /* 16-bit register */
-
-      modifyreg16(priv->base + offset, (uint16_t)clearbits,
-                  (uint16_t)setbits);
-    }
-}
-
-/****************************************************************************
- * Name: pulsecount_dumpregs
- *
- * Description:
- *   Dump all timer registers.
- *
- * Input Parameters:
- *   dev - A reference to the lower half pulsecount driver state structure
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
-
-#ifdef CONFIG_DEBUG_TIMER_INFO
-static void pulsecount_dumpregs(struct pulsecount_lowerhalf_s *dev,
-                                const char *msg)
-{
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-
-  _info("%s:\n", msg);
-  _info("  CR1: %04x CR2:  %04x SMCR:  %04x DIER:  %04x\n",
-          pulsecount_getreg(priv, STM32_GTIM_CR1_OFFSET),
-          pulsecount_getreg(priv, STM32_GTIM_CR2_OFFSET),
-          pulsecount_getreg(priv, STM32_GTIM_SMCR_OFFSET),
-          pulsecount_getreg(priv, STM32_GTIM_DIER_OFFSET));
-
-  _info("   SR: %04x EGR:  %04x CCMR1: %04x CCMR2: %04x\n",
-          pulsecount_getreg(priv, STM32_GTIM_SR_OFFSET),
-          pulsecount_getreg(priv, STM32_GTIM_EGR_OFFSET),
-          pulsecount_getreg(priv, STM32_GTIM_CCMR1_OFFSET),
-          pulsecount_getreg(priv, STM32_GTIM_CCMR2_OFFSET));
-
-  _info(" CCER: %04x CNT:  %04x PSC:   %04x ARR:   %04x\n",
-          pulsecount_getreg(priv, STM32_GTIM_CCER_OFFSET),
-          pulsecount_getreg(priv, STM32_GTIM_CNT_OFFSET),
-          pulsecount_getreg(priv, STM32_GTIM_PSC_OFFSET),
-          pulsecount_getreg(priv, STM32_GTIM_ARR_OFFSET));
-
-  if (priv->timid == 1 || priv->timid == 8)
-    {
-      _info("  RCR: %04x BDTR: %04x\n",
-          pulsecount_getreg(priv, STM32_ATIM_RCR_OFFSET),
-          pulsecount_getreg(priv, STM32_ATIM_BDTR_OFFSET));
-    }
-
-  _info(" CCR1: %04x CCR2: %04x CCR3:  %04x CCR4:  %04x\n",
-          pulsecount_getreg(priv, STM32_GTIM_CCR1_OFFSET),
-          pulsecount_getreg(priv, STM32_GTIM_CCR2_OFFSET),
-          pulsecount_getreg(priv, STM32_GTIM_CCR3_OFFSET),
-          pulsecount_getreg(priv, STM32_GTIM_CCR4_OFFSET));
-
-  _info("  DCR: %04x DMAR: %04x\n",
-      pulsecount_getreg(priv, STM32_GTIM_DCR_OFFSET),
-      pulsecount_getreg(priv, STM32_GTIM_DMAR_OFFSET));
-}
-#endif
-
-/****************************************************************************
- * Name: pulsecount_ccr_update
- ****************************************************************************/
-
-static int pulsecount_ccr_update(struct pulsecount_lowerhalf_s *dev,
-                                 uint8_t index, uint32_t ccr)
-{
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-  uint32_t offset = 0;
-
-  /* CCR channel indices are one-based to match timer channel numbers. */
-
-  switch (index)
-    {
-      case 1:
-        {
-          offset = STM32_GTIM_CCR1_OFFSET;
-          break;
-        }
-
-      case 2:
-        {
-          offset = STM32_GTIM_CCR2_OFFSET;
-          break;
-        }
-
-      case 3:
-        {
-          offset = STM32_GTIM_CCR3_OFFSET;
-          break;
-        }
-
-      case 4:
-        {
-          offset = STM32_GTIM_CCR4_OFFSET;
-          break;
-        }
-
-      default:
-        {
-          _err("ERROR: No such CCR: %u\n", index);
-          return -EINVAL;
-        }
-    }
-
-  /* Update CCR register */
-
-  pulsecount_putreg(priv, offset, ccr);
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: pulsecount_duty_update
- *
- * Description:
- *   Try to change only channel duty
- *
- * Input Parameters:
- *   dev     - A reference to the lower half driver state structure
- *   channel - Channel to by updated
- *   duty    - New duty
- *
- * Returned Value:
- *   Zero on success; a negated errno value on failure
- *
- ****************************************************************************/
-
-static int pulsecount_duty_update(struct pulsecount_lowerhalf_s *dev,
-                                  uint8_t channel, ub16_t duty)
-{
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-  uint32_t reload = 0;
-  uint32_t ccr    = 0;
-
-  /* We don't want compilation warnings if no DEBUGASSERT */
-
-  UNUSED(priv);
-
-  DEBUGASSERT(priv != NULL);
-
-  _info("TIM%u channel: %u duty: %08" PRIx32 "\n",
-          priv->timid, channel, duty);
-
-  /* Get the reload values */
-
-  reload = pulsecount_getreg(priv, STM32_GTIM_ARR_OFFSET);
-
-  /* Duty cycle:
-   *
-   * duty cycle = ccr / reload (fractional value)
-   */
-
-  ccr = b16toi(duty * reload + b16HALF);
-
-  _info("ccr: %" PRIu32 "\n", ccr);
-
-  /* Write corresponding CCR register */
-
-  return pulsecount_ccr_update(dev, channel, ccr);
-}
-
-/****************************************************************************
- * Name: pulsecount_frequency_update
- *
- * Description:
- *   Update a pulsecount timer frequency
- *
- ****************************************************************************/
-
-static int pulsecount_frequency_update(struct pulsecount_lowerhalf_s *dev,
-                                       uint32_t frequency)
-{
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-  uint32_t reload    = 0;
-  uint32_t timclk    = 0;
-  uint32_t prescaler = 0;
-
-  /* Calculate optimal values for the timer prescaler and for the timer
-   * reload register. If 'frequency' is the desired frequency, then
-   *
-   *   reload = timclk / frequency
-   *   timclk = pclk / presc
-   *
-   * Or,
-   *
-   *   reload = pclk / presc / frequency
-   *
-   * There are many solutions to this, but the best solution will be the one
-   * that has the largest reload value and the smallest prescaler value.
-   * That is the solution that should give us the most accuracy in the timer
-   * control.  Subject to:
-   *
-   *   0 <= presc  <= 65536
-   *   1 <= reload <= 65535
-   *
-   * So presc = pclk / 65535 / frequency would be optimal.
-   *
-   * Example:
-   *
-   *  pclk      = 42 MHz
-   *  frequency = 100 Hz
-   *
-   *  prescaler = 42,000,000 / 65,535 / 100
-   *            = 6.4 (or 7 -- taking the ceiling always)
-   *  timclk    = 42,000,000 / 7
-   *            = 6,000,000
-   *  reload    = 6,000,000 / 100
-   *            = 60,000
-   */
-
-  prescaler = (priv->pclk / frequency + 65534) / 65535;
-  if (prescaler < 1)
-    {
-      prescaler = 1;
-    }
-  else if (prescaler > 65536)
-    {
-      prescaler = 65536;
-    }
-
-  timclk = priv->pclk / prescaler;
-
-  reload = timclk / frequency;
-  if (reload < 2)
-    {
-      reload = 1;
-    }
-  else if (reload > 65535)
-    {
-      reload = 65535;
-    }
-  else
-    {
-      reload--;
-    }
-
-  _info("TIM%u PCLK: %" PRIu32" frequency: %" PRIu32
-          " TIMCLK: %" PRIu32 " "
-          "prescaler: %" PRIu32 " reload: %" PRIu32 "\n",
-          priv->timid, priv->pclk, frequency, timclk, prescaler, reload);
-
-  /* Set the reload and prescaler values */
-
-  pulsecount_putreg(priv, STM32_GTIM_ARR_OFFSET, reload);
-  pulsecount_putreg(priv, STM32_GTIM_PSC_OFFSET, (uint16_t)(prescaler - 1));
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: pulsecount_timer_configure
- *
- * Description:
- *   Initial configuration for pulsecount timer
- *
- ****************************************************************************/
-
-static int pulsecount_timer_configure(struct stm32_tim_s *priv)
-{
-  uint16_t cr1 = 0;
-
-  /* Set up the advanced timer CR1 register. */
-
-  cr1 = pulsecount_getreg(priv, STM32_GTIM_CR1_OFFSET);
-
-  /* Pulsecount always uses edge-aligned up-counting mode. */
-
-  cr1 &= ~(GTIM_CR1_DIR | GTIM_CR1_CMS_MASK);
-  cr1 |= GTIM_CR1_EDGE;
-  cr1 &= ~GTIM_CR1_CKD_MASK;
-  cr1 |= priv->t_dts << GTIM_CR1_CKD_SHIFT;
-
-  /* Enable ARR preload to preserve the previous pulsecount behavior. */
-
-  cr1 |= GTIM_CR1_ARPE;
-
-  /* Write CR1 */
-
-  pulsecount_putreg(priv, STM32_GTIM_CR1_OFFSET, cr1);
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: pulsecount_channel_configure
- *
- * Description:
- *   Configure pulsecount output compare for a channel
- *
- ****************************************************************************/
-
-static int pulsecount_channel_configure(struct pulsecount_lowerhalf_s *dev,
-                                        uint8_t channel)
-{
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-  uint32_t chanmode = 0;
-  uint32_t ocmode   = 0;
-  uint32_t ccmr     = 0;
-  uint32_t offset   = 0;
-  int      ret      = OK;
-
-  /* Configure output compare mode */
-
-  chanmode = GTIM_CCMR_MODE_PWM1;
-
-  /* Get CCMR offset */
-
-  switch (channel)
-    {
-      case 1:
-      case 2:
-        {
-          offset = STM32_GTIM_CCMR1_OFFSET;
-          break;
-        }
-
-      case 3:
-      case 4:
-        {
-          offset = STM32_GTIM_CCMR2_OFFSET;
-          break;
-        }
-
-      default:
-        {
-          _err("ERROR: No such channel: %u\n", channel);
-          ret = -EINVAL;
-          goto errout;
-        }
-    }
-
-  /* Get current registers */
-
-  ccmr = pulsecount_getreg(priv, offset);
-
-  /* output compare configuration.
-   * NOTE: The CCMRx registers are identical if the channels are outputs.
-   */
-
-  switch (channel)
-    {
-      /* Configure channel 1/3 */
-
-      case 1:
-      case 3:
-        {
-          ccmr &= ~(ATIM_CCMR1_CC1S_MASK | ATIM_CCMR1_OC1M_MASK |
-                     ATIM_CCMR1_OC1PE);
-          ocmode |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC1S_SHIFT);
-          ocmode |= (chanmode << ATIM_CCMR1_OC1M_SHIFT);
-          ocmode |= ATIM_CCMR1_OC1PE;
-#ifdef HAVE_IP_TIMERS_V2
-          ccmr &= ~(ATIM_CCMR1_OC1M);
-#endif
-          break;
-        }
-
-      /* Configure channel 2/4 */
-
-      case 2:
-      case 4:
-        {
-          ccmr &= ~(ATIM_CCMR1_CC2S_MASK | ATIM_CCMR1_OC2M_MASK |
-                     ATIM_CCMR1_OC2PE);
-          ocmode |= (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC2S_SHIFT);
-          ocmode |= (chanmode << ATIM_CCMR1_OC2M_SHIFT);
-          ocmode |= ATIM_CCMR1_OC2PE;
-#ifdef HAVE_IP_TIMERS_V2
-          ccmr &= ~(ATIM_CCMR1_OC2M);
-#endif
-          break;
-        }
-    }
-
-  /* Set the selected output compare configuration */
-
-  ccmr |= ocmode;
-
-  /* Write CCMRx registers */
-
-  pulsecount_putreg(priv, offset, ccmr);
-
-errout:
-  return ret;
-}
-
-/****************************************************************************
- * Name: pulsecount_output_configure
- *
- * Description:
- *   Configure pulsecount output for given channel
- *
- ****************************************************************************/
-
-static int pulsecount_output_configure(struct stm32_tim_s *priv,
-                                       struct stm32_chan_s *chan)
-{
-  uint32_t cr2  = 0;
-  uint32_t ccer = 0;
-  uint8_t  channel = 0;
-
-  /* Get channel */
-
-  channel = chan->channel;
-
-  /* Get current registers state */
-
-  cr2  = pulsecount_getreg(priv, STM32_GTIM_CR2_OFFSET);
-  ccer = pulsecount_getreg(priv, STM32_GTIM_CCER_OFFSET);
-
-  /* | OISx | IDLE | advanced timers | CR2 register
-   * | CCxP | POL  | all pulsecount timers | CCER register
-   */
-
-  /* Configure output polarity (all pulsecount timers) */
-
-  if (chan->out1.pol == PULSECOUNT_POL_NEG)
-    {
-      ccer |= (GTIM_CCER_CC1P << ((channel - 1) * 4));
-    }
-  else
-    {
-      ccer &= ~(GTIM_CCER_CC1P << ((channel - 1) * 4));
-    }
-
-  if (priv->timtype == TIMTYPE_ADVANCED)
-    {
-      /* Configure output IDLE State */
-
-      if (chan->out1.idle == PULSECOUNT_IDLE_ACTIVE)
-        {
-          cr2 |= (ATIM_CR2_OIS1 << ((channel - 1) * 2));
-        }
-      else
-        {
-          cr2 &= ~(ATIM_CR2_OIS1 << ((channel - 1) * 2));
-        }
-    }
-
-  /* Write registers */
-
-  pulsecount_modifyreg(priv, STM32_GTIM_CR2_OFFSET, 0, cr2);
-  pulsecount_modifyreg(priv, STM32_GTIM_CCER_OFFSET, 0, ccer);
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: pulsecount_outputs_enable
- *
- * Description:
- *   Enable/disable given timer pulsecount outputs.
- *
- *   NOTE: This is bulk operation - we can enable/disable many outputs
- *   at one time
- *
- * Input Parameters:
- *   dev     - A reference to the lower half driver state structure
- *   outputs - outputs to set (look at enum stm32_pulsecount_chan_e)
- *   state   - Enable/disable operation
- *
- ****************************************************************************/
-
-static int pulsecount_outputs_enable(struct pulsecount_lowerhalf_s *dev,
-                                     uint16_t outputs, bool state)
-{
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-  uint32_t ccer   = 0;
-  uint32_t regval = 0;
-
-  /* Get current register state */
-
-  ccer = pulsecount_getreg(priv, STM32_GTIM_CCER_OFFSET);
-
-  /* Get outputs configuration */
-
-  regval |= ((outputs & (1 << 0))  ? GTIM_CCER_CC1E  : 0);
-  regval |= ((outputs & (1 << 2))  ? GTIM_CCER_CC2E  : 0);
-  regval |= ((outputs & (1 << 4))  ? GTIM_CCER_CC3E  : 0);
-  regval |= ((outputs & (1 << 6))  ? GTIM_CCER_CC4E  : 0);
-
-  if (state == true)
-    {
-      /* Enable outputs - set bits */
-
-      ccer |= regval;
-    }
-  else
-    {
-      /* Disable outputs - reset bits */
-
-      ccer &= ~regval;
-    }
-
-  /* Write register */
-
-  pulsecount_putreg(priv, STM32_GTIM_CCER_OFFSET, ccer);
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: pulsecount_moe_enable
- ****************************************************************************/
-
-static void pulsecount_moe_enable(struct pulsecount_lowerhalf_s *dev,
-                                  bool enable)
-{
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-
-  if (enable)
-    {
-      pulsecount_modifyreg(priv, STM32_ATIM_BDTR_OFFSET, 0, ATIM_BDTR_MOE);
-    }
-  else
-    {
-      pulsecount_modifyreg(priv, STM32_ATIM_BDTR_OFFSET, ATIM_BDTR_MOE, 0);
-    }
-}
-
-/****************************************************************************
- * Name: pulsecount_outputs_from_channels
- *
- * Description:
- *   Get enabled outputs configuration from the pulsecount timer state
- *
- ****************************************************************************/
-
-static uint16_t
-pulsecount_outputs_from_channels(struct stm32_tim_s *priv, uint8_t selected)
-{
-  uint16_t outputs = 0;
-  uint8_t  channel;
-
-  channel = priv->channel.channel;
-
-  if (channel != 0 && (selected == 0 || channel == selected) &&
-      priv->channel.out1.in_use == 1)
-    {
-      outputs = (1 << ((channel - 1) * 2));
-    }
-
-  return outputs;
-}
-
-/****************************************************************************
- * Name: pulsecount_configure
- *
- * Description:
- *   Configure pulsecount timer in PULSECOUNT mode
- *
- ****************************************************************************/
-
-static int pulsecount_configure(struct pulsecount_lowerhalf_s *dev)
-{
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-  uint16_t outputs = 0;
-  int     ret      = OK;
-
-  /* NOTE: leave timer counter disabled and all outputs disabled! */
-
-  /* Disable the timer until we get it configured */
-
-  pulsecount_modifyreg(priv, STM32_GTIM_CR1_OFFSET, GTIM_CR1_CEN, 0);
-
-  /* Get configured outputs */
-
-  outputs = pulsecount_outputs_from_channels(priv, 0);
-
-  /* Disable configured outputs before the timer is reconfigured. */
-
-  ret = pulsecount_outputs_enable(dev, outputs, false);
-  if (ret < 0)
-    {
-      goto errout;
-    }
-
-  /* Initial timer configuration */
-
-  ret = pulsecount_timer_configure(priv);
-  if (ret < 0)
-    {
-      goto errout;
-    }
-
-  /* Disable software break (enable outputs) */
-
-  pulsecount_moe_enable(dev, true);
-
-  /* Configure timer channels */
-
-  if (priv->channel.channel != 0)
-    {
-      pulsecount_channel_configure(dev, priv->channel.channel);
-      pulsecount_output_configure(priv, &priv->channel);
-    }
-
-errout:
-  return ret;
-}
-
-/****************************************************************************
- * Name: pulsecount_timer
- *
- * Description:
- *   (Re-)initialize the timer resources and start the pulsed output
- *
- * Input Parameters:
- *   dev  - A reference to the lower half pulsecount driver state structure
- *   info - A reference to the characteristics of the pulsed output
- *
- * Returned Value:
- *   Zero on success; a negated errno value on failure
- *
- * This split keeps pulsecount as the existing single-channel mode.
- *
- ****************************************************************************/
-
-static int pulsecount_timer(struct pulsecount_lowerhalf_s *dev,
-                            const struct pulsecount_info_s *info)
-{
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-  ub16_t    duty    = 0;
-  uint8_t   channel = 0;
-  uint16_t  outputs = 0;
-  int       ret     = OK;
-
-  /* If we got here then the timer instance supports pulsecount output. */
-
-  DEBUGASSERT(priv != NULL && info != NULL);
-
-  _info("TIM%u channel: %u high: %" PRIu32 " ns low: %" PRIu32
-          " ns count: %" PRIu32 "\n",
-          priv->timid, priv->channel.channel, info->high_ns,
-          info->low_ns, info->count);
-
-  DEBUGASSERT(pulsecount_frequency(info) > 0);
-
-  /* Channel specific setup */
-
-  duty    = pulsecount_duty(info);
-  channel = priv->channel.channel;
-
-  /* Disable all interrupts and DMA requests, clear all pending status */
-
-  pulsecount_putreg(priv, STM32_GTIM_DIER_OFFSET, 0);
-  pulsecount_putreg(priv, STM32_GTIM_SR_OFFSET, 0);
-
-  /* Set timer frequency */
-
-  ret = pulsecount_frequency_update(dev, pulsecount_frequency(info));
-  if (ret < 0)
-    {
-      goto errout;
-    }
-
-  /* Update duty cycle */
-
-  ret = pulsecount_duty_update(dev, channel, duty);
-  if (ret < 0)
-    {
-      goto errout;
-    }
-
-  /* If a non-zero repetition count has been selected, then set the
-   * repetition counter to the count-1 (pulsecount_start() has already
-   * assured us that the count value is within range).
-   */
-
-  if (info->count > 0)
-    {
-      /* Save the remaining count and the number of counts that will have
-       * elapsed on the first interrupt.
-       */
-
-      /* If the first interrupt occurs at the end end of the first
-       * repetition count, then the count will be the same as the RCR
-       * value.
-       */
-
-      priv->prev  = pulsecount_count(info->count);
-      pulsecount_putreg(priv, STM32_ATIM_RCR_OFFSET, priv->prev - 1);
-
-      /* Generate an update event to reload the prescaler.  This should
-       * preload the RCR into active repetition counter.
-       */
-
-      pulsecount_putreg(priv, STM32_GTIM_EGR_OFFSET, GTIM_EGR_UG);
-
-      /* Now set the value of the RCR that will be loaded on the next
-       * update event.
-       */
-
-      priv->count = info->count;
-      priv->curr  = pulsecount_count(info->count - priv->prev);
-      pulsecount_putreg(priv, STM32_ATIM_RCR_OFFSET, priv->curr - 1);
-    }
-
-  /* Otherwise, just clear the repetition counter */
-
-  else
-    {
-      /* Set the repetition counter to zero */
-
-      pulsecount_putreg(priv, STM32_ATIM_RCR_OFFSET, 0);
-
-      /* Generate an update event to reload the prescaler */
-
-      pulsecount_putreg(priv, STM32_GTIM_EGR_OFFSET, GTIM_EGR_UG);
-    }
-
-  /* Get configured outputs */
-
-  outputs = pulsecount_outputs_from_channels(priv, channel);
-
-  /* Enable output */
-
-  ret = pulsecount_outputs_enable(dev, outputs, true);
-  if (ret < 0)
-    {
-      goto errout;
-    }
-
-  /* Setup update interrupt. If info->count is > 0, then we can
-   * be assured that pulsecount_start() has already verified: (1) that
-   * this is an advanced timer, and that (2) the repetition count is within
-   * range.
-   */
-
-  if (info->count > 0)
-    {
-      /* Clear all pending interrupts and enable the update interrupt. */
-
-      pulsecount_putreg(priv, STM32_GTIM_SR_OFFSET, 0);
-      pulsecount_putreg(priv, STM32_GTIM_DIER_OFFSET, GTIM_DIER_UIE);
-
-      /* Enable the timer */
-
-      pulsecount_modifyreg(priv, STM32_GTIM_CR1_OFFSET, 0, GTIM_CR1_CEN);
-
-      /* And enable timer interrupts at the NVIC */
-
-      up_enable_irq(priv->irq);
-    }
-
-  pulsecount_dumpregs(dev, "After starting");
-
-errout:
-  return ret;
-}
-
-/****************************************************************************
- * Name: pulsecount_interrupt
- *
- * Description:
- *   Handle timer interrupts.
- *
- * Input Parameters:
- *   dev - A reference to the lower half pulsecount driver state structure
- *
- * Returned Value:
- *   Zero on success; a negated errno value on failure
- *
- ****************************************************************************/
-
-static int pulsecount_interrupt(struct pulsecount_lowerhalf_s *dev)
-{
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-  uint16_t regval;
-
-  /* Verify that this is an update interrupt.  Nothing else is expected. */
-
-  regval = pulsecount_getreg(priv, STM32_ATIM_SR_OFFSET);
-  DEBUGASSERT((regval & ATIM_SR_UIF) != 0);
-
-  /* Clear the UIF interrupt bit */
-
-  pulsecount_putreg(priv, STM32_ATIM_SR_OFFSET, (regval & ~ATIM_SR_UIF));
-
-  /* Calculate the new count by subtracting the number of pulses
-   * since the last interrupt.
-   */
-
-  if (priv->count <= priv->prev)
-    {
-      /* We are finished.  Turn off the master output to stop the output as
-       * quickly as possible.
-       */
-
-      pulsecount_moe_enable(dev, false);
-
-      /* Disable first interrupts, stop and reset the timer */
-
-      pulsecount_ll_stop(dev);
-
-      /* Then perform the callback into the upper half driver */
-
-      pulsecount_expired(priv->handle);
-
-      priv->handle = NULL;
-      priv->count  = 0;
-      priv->prev   = 0;
-      priv->curr   = 0;
-    }
-  else
-    {
-      /* Decrement the count of pulses remaining using the number of
-       * pulses generated since the last interrupt.
-       */
-
-      priv->count -= priv->prev;
-
-      /* Set up the next RCR.  Set 'prev' to the value of the RCR that
-       * was loaded when the update occurred (just before this interrupt)
-       * and set 'curr' to the current value of the RCR register (which
-       * will bet loaded on the next update event).
-       */
-
-      priv->prev = priv->curr;
-      priv->curr = pulsecount_count(priv->count - priv->prev);
-      pulsecount_putreg(priv, STM32_ATIM_RCR_OFFSET, priv->curr - 1);
-    }
-
-  /* Now all of the time critical stuff is done so we can do some debug
-   * output.
-   */
-
-  _info("Update interrupt SR: %04" PRIx16 " prev: %u curr: %u"
-          " count: %" PRIu32 "\n",
-          regval, (unsigned int)priv->prev, (unsigned int)priv->curr,
-          priv->count);
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: pulsecount_tim1/8interrupt
- *
- * Description:
- *   Handle timer 1 and 8 interrupts.
- *
- * Input Parameters:
- *   Standard NuttX interrupt inputs
- *
- * Returned Value:
- *   Zero on success; a negated errno value on failure
- *
- ****************************************************************************/
-
-#ifdef CONFIG_STM32_TIM1_PULSECOUNT
-static int pulsecount_tim1interrupt(int irq, void *context, void *arg)
-{
-  return pulsecount_interrupt((struct pulsecount_lowerhalf_s *)
-                              &g_pulsecount1dev);
-}
-#endif /* CONFIG_STM32_TIM1_PULSECOUNT */
-
-#ifdef CONFIG_STM32_TIM8_PULSECOUNT
-static int pulsecount_tim8interrupt(int irq, void *context, void *arg)
-{
-  return pulsecount_interrupt((struct pulsecount_lowerhalf_s *)
-                              &g_pulsecount8dev);
-}
-#endif /* CONFIG_STM32_TIM8_PULSECOUNT */
-
-/****************************************************************************
- * Name: pulsecount_count
- *
- * Description:
- *   Pick an optimal pulse count to program the RCR.
- *
- * Input Parameters:
- *   count - The total count remaining
- *
- * Returned Value:
- *   The recommended pulse count
- *
- ****************************************************************************/
-
-static uint8_t pulsecount_count(uint32_t count)
-{
-  /* Use the advanced-timer repetition counter limit. */
-
-  /* The the remaining pulse count is less than or equal to the maximum, the
-   * just return the count.
-   */
-
-  if (count <= ATIM_RCR_REP_MAX)
-    {
-      return (uint8_t)count;
-    }
-
-  /* Otherwise, we have to be careful.  We do not want a small number of
-   * counts at the end because we might have trouble responding fast enough.
-   * If the remaining count is less than 150% of the maximum, then return
-   * half of the maximum.  In this case the final sequence will be between 64
-   * and 128.
-   */
-
-  else if (count < (3 * ATIM_RCR_REP_MAX / 2))
-    {
-      return (uint8_t)((ATIM_RCR_REP_MAX + 1) >> 1);
-    }
-
-  /* Otherwise, return the maximum.  The final count will be 64 or more */
-
-  else
-    {
-      return (uint8_t)ATIM_RCR_REP_MAX;
-    }
-}
-
-/****************************************************************************
- * Name: pulsecount_set_apb_clock
- *
- * Description:
- *   Enable or disable APB clock for the timer peripheral
- *
- * Input Parameters:
- *   priv - A reference to the pulsecount block status
- *   on   - Enable clock if 'on' is 'true' and disable if 'false'
- *
- ****************************************************************************/
-
-static int pulsecount_set_apb_clock(struct stm32_tim_s *priv, bool on)
-{
-  uint32_t en_bit  = 0;
-  uint32_t regaddr = 0;
-  int      ret     = OK;
-
-  _info("timer %d clock enable: %d\n", priv->timid, on ? 1 : 0);
-
-  /* Determine which timer to configure */
-
-  switch (priv->timid)
-    {
-#ifdef CONFIG_STM32_TIM1_PULSECOUNT
-      case 1:
-        {
-          regaddr = TIMRCCEN_TIM1;
-          en_bit  = TIMEN_TIM1;
-          break;
-        }
-#endif
-
-#ifdef CONFIG_STM32_TIM8_PULSECOUNT
-      case 8:
-        {
-          regaddr = TIMRCCEN_TIM8;
-          en_bit  = TIMEN_TIM8;
-          break;
-        }
-#endif
-
-      default:
-        {
-          _err("ERROR: No such timer configured %d\n", priv->timid);
-          ret = -EINVAL;
-          goto errout;
-        }
-    }
-
-  /* Enable/disable APB 1/2 clock for timer */
-
-  _info("RCC_APBxENR base: %08" PRIx32 "  bits: %04" PRIx32 "\n",
-          regaddr, en_bit);
-
-  if (on)
-    {
-      modifyreg32(regaddr, 0, en_bit);
-    }
-  else
-    {
-      modifyreg32(regaddr, en_bit, 0);
-    }
-
-errout:
-  return ret;
-}
-
-/****************************************************************************
- * Name: pulsecount_ll_setup
- *
- * Description:
- *   This method is called when the driver is opened.  The lower half driver
- *   should configure and initialize the device so that it is ready for use.
- *   It should not, however, output pulses until the start method is called.
- *
- * Input Parameters:
- *   dev - A reference to the lower half pulsecount driver state structure
- *
- * Returned Value:
- *   Zero on success; a negated errno value on failure
- *
- * Assumptions:
- *   APB1 or 2 clocking for the GPIOs has already been configured by the RCC
- *   logic at power up.
- *
- ****************************************************************************/
-
-static int pulsecount_ll_setup(struct pulsecount_lowerhalf_s *dev)
-{
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-  uint32_t pincfg = 0;
-  int      ret    = OK;
-
-  _info("TIM%u\n", priv->timid);
-
-  /* Enable APB1/2 clocking for timer. */
-
-  ret = pulsecount_set_apb_clock(priv, true);
-  if (ret < 0)
-    {
-      goto errout;
-    }
-
-  pulsecount_dumpregs(dev, "Initially");
-
-  /* Configure the pulsecount output pins, but do not start the timer yet */
-
-  if (priv->channel.out1.in_use == 1)
-    {
-      /* Do not configure the pin if pincfg is not specified.
-       * This prevents overwriting the PA0 configuration if the
-       * channel is used internally.
-       */
-
-      pincfg = priv->channel.out1.pincfg;
-      if (pincfg != 0)
-        {
-          _info("pincfg: %08" PRIx32 "\n", pincfg);
-
-          stm32_configgpio(pincfg);
-          pulsecount_dumpgpio(pincfg, "pulsecount setup");
-        }
-    }
-
-errout:
-  return ret;
-}
-
-/****************************************************************************
- * Name: pulsecount_ll_shutdown
- *
- * Description:
- *   This method is called when the driver is closed.  The lower half driver
- *   stop pulsed output, free any resources, disable the timer hardware, and
- *   put the system into the lowest possible power usage state
- *
- * Input Parameters:
- *   dev - A reference to the lower half pulsecount driver state structure
- *
- * Returned Value:
- *   Zero on success; a negated errno value on failure
- *
- ****************************************************************************/
-
-static int pulsecount_ll_shutdown(struct pulsecount_lowerhalf_s *dev)
-{
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-  uint32_t pincfg = 0;
-  int      ret    = OK;
-
-  _info("TIM%u\n", priv->timid);
-
-  /* Make sure that the output has been stopped */
-
-  pulsecount_ll_stop(dev);
-
-  /* Disable APB1/2 clocking for timer. */
-
-  ret = pulsecount_set_apb_clock(priv, false);
-  if (ret < 0)
-    {
-      goto errout;
-    }
-
-  /* Then put the GPIO pins back to the default state */
-
-  pincfg = priv->channel.out1.pincfg;
-  if (pincfg != 0)
-    {
-      _info("pincfg: %08" PRIx32 "\n", pincfg);
-
-      pincfg &= (GPIO_PORT_MASK | GPIO_PIN_MASK);
-      pincfg |= PINCFG_DEFAULT;
-
-      stm32_configgpio(pincfg);
-    }
-
-errout:
-  return ret;
-}
-
-/****************************************************************************
- * Name: pulsecount_ll_stop
- *
- * Description:
- *   Stop the pulsed output and reset the timer resources
- *
- * Input Parameters:
- *   dev - A reference to the lower half pulsecount driver state structure
- *
- * Returned Value:
- *   Zero on success; a negated errno value on failure
- *
- * Assumptions:
- *   This function is called to stop the pulsed output at anytime.  This
- *   method is also called from the timer interrupt handler when a repetition
- *   count expires... automatically stopping the timer.
- *
- ****************************************************************************/
-
-static int pulsecount_ll_stop(struct pulsecount_lowerhalf_s *dev)
-{
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-  irqstate_t flags    = 0;
-  uint16_t   outputs  = 0;
-  int        ret = OK;
-
-  _info("TIM%u\n", priv->timid);
-
-  /* Disable interrupts momentary to stop any ongoing timer processing and
-   * to prevent any concurrent access to the reset register.
-   */
-
-  flags = enter_critical_section();
-
-  /* Stopped so frequency is zero */
-
-  priv->frequency = 0;
-
-  /* Disable further interrupts and stop the timer */
-
-  pulsecount_putreg(priv, STM32_GTIM_DIER_OFFSET, 0);
-  pulsecount_putreg(priv, STM32_GTIM_SR_OFFSET, 0);
-
-  /* Disable the timer and timer outputs */
-
-  pulsecount_modifyreg(priv, STM32_GTIM_CR1_OFFSET, GTIM_CR1_CEN, 0);
-  outputs = pulsecount_outputs_from_channels(priv, 0);
-  ret = pulsecount_outputs_enable(dev, outputs, false);
-
-  /* Clear all channels */
-
-  pulsecount_putreg(priv, STM32_GTIM_CCR1_OFFSET, 0);
-  pulsecount_putreg(priv, STM32_GTIM_CCR2_OFFSET, 0);
-  pulsecount_putreg(priv, STM32_GTIM_CCR3_OFFSET, 0);
-  pulsecount_putreg(priv, STM32_GTIM_CCR4_OFFSET, 0);
-
-  leave_critical_section(flags);
-
-  pulsecount_dumpregs(dev, "After stop");
-
-  return ret;
-}
-
-/****************************************************************************
- * Name: pulsecount_ll_ioctl
- *
- * Description:
- *   Lower-half logic may support platform-specific ioctl commands
- *
- * Input Parameters:
- *   dev - A reference to the lower half pulsecount driver state structure
- *   cmd - The ioctl command
- *   arg - The argument accompanying the ioctl command
- *
- * Returned Value:
- *   Zero on success; a negated errno value on failure
- *
- ****************************************************************************/
-
-static int pulsecount_ll_ioctl(struct pulsecount_lowerhalf_s *dev, int cmd,
-                               unsigned long arg)
-{
-#ifdef CONFIG_DEBUG_TIMER_INFO
-  struct stm32_tim_s *priv = (struct stm32_tim_s *)dev;
-
-  /* There are no platform-specific ioctl commands */
-
-  _info("TIM%u\n", priv->timid);
-#endif
-  return -ENOTTY;
-}
-
-static int pulsecount_setup(struct pulsecount_lowerhalf_s *dev)
-{
-  struct stm32_pulsecount_s *pulse = (struct stm32_pulsecount_s *)dev;
-  int ret;
-
-  ret = pulsecount_ll_setup((struct pulsecount_lowerhalf_s *)pulse->timer);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  return pulsecount_configure((struct pulsecount_lowerhalf_s *)pulse->timer);
-}
-
-static int pulsecount_shutdown(struct pulsecount_lowerhalf_s *dev)
-{
-  struct stm32_pulsecount_s *pulse = (struct stm32_pulsecount_s *)dev;
-  return pulsecount_ll_shutdown((struct pulsecount_lowerhalf_s *)
-                                pulse->timer);
-}
-
-static int pulsecount_start(struct pulsecount_lowerhalf_s *dev,
-                            const struct pulsecount_info_s *info,
-                            void *handle)
-{
-  struct stm32_pulsecount_s *pulse = (struct stm32_pulsecount_s *)dev;
-  struct stm32_tim_s *priv = pulse->timer;
-
-  /* Check if a pulsecount has been selected */
-
-  if (info->count > 0)
-    {
-      /* Only the advanced timers (TIM1,8 can support the pulse counting)
-       */
-
-      if (priv->timtype != TIMTYPE_ADVANCED)
-        {
-          _err("ERROR: TIM%u cannot support pulse count: %" PRIu32 "\n",
-                 priv->timid, info->count);
-          return -EPERM;
-        }
-    }
-
-  /* Save the handle */
-
-  priv->handle = handle;
-
-  /* Start the time */
-
-  return pulsecount_timer((struct pulsecount_lowerhalf_s *)priv, info);
-}
-
-static int pulsecount_stop(struct pulsecount_lowerhalf_s *dev)
-{
-  struct stm32_pulsecount_s *pulse = (struct stm32_pulsecount_s *)dev;
-  return pulsecount_ll_stop((struct pulsecount_lowerhalf_s *)pulse->timer);
-}
-
-static int pulsecount_ioctl(struct pulsecount_lowerhalf_s *dev,
-                            int cmd, unsigned long arg)
-{
-  struct stm32_pulsecount_s *pulse = (struct stm32_pulsecount_s *)dev;
-  return pulsecount_ll_ioctl((struct pulsecount_lowerhalf_s *)pulse->timer,
-                             cmd, arg);
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-struct pulsecount_lowerhalf_s *stm32_pulsecountinitialize(int timer)
-{
-  struct stm32_pulsecount_s *lower = NULL;
-
-  _info("TIM%u\n", timer);
-
-  switch (timer)
-    {
-#ifdef CONFIG_STM32_TIM1_PULSECOUNT
-      case 1:
-        {
-          lower = &g_pulsecount1lower;
-          irq_attach(lower->timer->irq, pulsecount_tim1interrupt, NULL);
-          up_disable_irq(lower->timer->irq);
-          break;
-        }
-#endif
-
-#ifdef CONFIG_STM32_TIM8_PULSECOUNT
-      case 8:
-        {
-          lower = &g_pulsecount8lower;
-          irq_attach(lower->timer->irq, pulsecount_tim8interrupt, NULL);
-          up_disable_irq(lower->timer->irq);
-          break;
-        }
-#endif
-
-      default:
-        {
-          _err("ERROR: TIM%d does not support pulse count\n", timer);
-          return NULL;
-        }
-    }
-
-  return (struct pulsecount_lowerhalf_s *)lower;
-}
diff --git a/arch/arm/src/stm32c0/stm32.h b/arch/arm/src/stm32c0/stm32.h
index 7d1c5ae3476..b12ea4f4565 100644
--- a/arch/arm/src/stm32c0/stm32.h
+++ b/arch/arm/src/stm32c0/stm32.h
@@ -43,6 +43,7 @@
 #include "stm32_pwr.h"
 #include "stm32_rcc.h"
 #include "stm32_spi.h"
+#include "stm32_tim.h"
 #include "stm32_uart.h"
 #include "stm32_lowputc.h"
 #include "stm32_adc.h"
diff --git a/arch/arm/src/stm32f0/stm32.h b/arch/arm/src/stm32f0/stm32.h
index fabdd48a625..bd3ce82e9d7 100644
--- a/arch/arm/src/stm32f0/stm32.h
+++ b/arch/arm/src/stm32f0/stm32.h
@@ -43,6 +43,7 @@
 #include "stm32_pwr.h"
 #include "stm32_rcc.h"
 #include "stm32_spi.h"
+#include "stm32_tim.h"
 #include "stm32_uart.h"
 #include "stm32_lowputc.h"
 #include "stm32_adc.h"
diff --git a/arch/arm/src/stm32f7/CMakeLists.txt 
b/arch/arm/src/stm32f7/CMakeLists.txt
index 92f1356a9cf..35b89101b15 100644
--- a/arch/arm/src/stm32f7/CMakeLists.txt
+++ b/arch/arm/src/stm32f7/CMakeLists.txt
@@ -178,10 +178,6 @@ if(CONFIG_STM32_PWM)
   list(APPEND SRCS stm32_pwm.c)
 endif()
 
-if(CONFIG_PULSECOUNT)
-  list(APPEND SRCS stm32_pulsecount.c)
-endif()
-
 if(CONFIG_STM32_FOC)
   list(APPEND SRCS stm32_foc.c)
 endif()
diff --git a/arch/arm/src/stm32f7/Make.defs b/arch/arm/src/stm32f7/Make.defs
index 32026d5e54a..30637c137f5 100644
--- a/arch/arm/src/stm32f7/Make.defs
+++ b/arch/arm/src/stm32f7/Make.defs
@@ -179,10 +179,6 @@ ifeq ($(CONFIG_STM32_PWM),y)
 CHIP_CSRCS += stm32_pwm.c
 endif
 
-ifeq ($(CONFIG_STM32_PULSECOUNT),y)
-CHIP_CSRCS += stm32_pulsecount.c
-endif
-
 ifeq ($(CONFIG_STM32_FOC),y)
 CHIP_CSRCS += stm32_foc.c
 endif
diff --git a/arch/arm/src/stm32f7/stm32_pulsecount.h 
b/arch/arm/src/stm32f7/stm32_pulsecount.h
deleted file mode 100644
index 7261a99c491..00000000000
--- a/arch/arm/src/stm32f7/stm32_pulsecount.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/****************************************************************************
- * arch/arm/src/stm32f7/stm32_pulsecount.h
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-#ifndef __ARCH_ARM_SRC_STM32F7_STM32_PULSECOUNT_H
-#define __ARCH_ARM_SRC_STM32F7_STM32_PULSECOUNT_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-#include <nuttx/timers/pulsecount.h>
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-struct pulsecount_lowerhalf_s *stm32_pulsecountinitialize(int timer);
-
-#endif /* __ARCH_ARM_SRC_STM32F7_STM32_PULSECOUNT_H */
diff --git a/arch/arm/src/stm32g0/stm32.h b/arch/arm/src/stm32g0/stm32.h
index 9e70f1bf95f..243e25e7d39 100644
--- a/arch/arm/src/stm32g0/stm32.h
+++ b/arch/arm/src/stm32g0/stm32.h
@@ -43,6 +43,7 @@
 #include "stm32_pwr.h"
 #include "stm32_rcc.h"
 #include "stm32_spi.h"
+#include "stm32_tim.h"
 #include "stm32_uart.h"
 #include "stm32_lowputc.h"
 #include "stm32_adc.h"
diff --git a/arch/arm/src/stm32h5/CMakeLists.txt 
b/arch/arm/src/stm32h5/CMakeLists.txt
index f413964d7b8..249a64c3136 100644
--- a/arch/arm/src/stm32h5/CMakeLists.txt
+++ b/arch/arm/src/stm32h5/CMakeLists.txt
@@ -115,10 +115,6 @@ if(CONFIG_STM32_PWM)
   list(APPEND SRCS stm32_pwm.c)
 endif()
 
-if(CONFIG_PULSECOUNT)
-  list(APPEND SRCS stm32_pulsecount.c)
-endif()
-
 # Required chip type specific files
 
 if(CONFIG_STM32_STM32H5XXXX)
diff --git a/arch/arm/src/stm32h5/Make.defs b/arch/arm/src/stm32h5/Make.defs
index ec8db4beccf..fd569978cb4 100644
--- a/arch/arm/src/stm32h5/Make.defs
+++ b/arch/arm/src/stm32h5/Make.defs
@@ -112,10 +112,6 @@ ifeq ($(CONFIG_STM32_PWM),y)
 CHIP_CSRCS += stm32_pwm.c
 endif
 
-ifeq ($(CONFIG_STM32_PULSECOUNT),y)
-CHIP_CSRCS += stm32_pulsecount.c
-endif
-
 # Required chip type specific files
 
 ifeq ($(CONFIG_STM32_STM32H5XXXX),y)
diff --git a/arch/arm/src/stm32h5/stm32.h b/arch/arm/src/stm32h5/stm32.h
index 7011cf4f5d2..25d810170aa 100644
--- a/arch/arm/src/stm32h5/stm32.h
+++ b/arch/arm/src/stm32h5/stm32.h
@@ -47,6 +47,7 @@
 #include "stm32_lowputc.h"
 #include "stm32_pwr.h"
 #include "stm32_rcc.h"
+#include "stm32_tim.h"
 #include "stm32_uart.h"
 #include "stm32_usbfs.h"
 
diff --git a/arch/arm/src/stm32h5/stm32_pulsecount.h 
b/arch/arm/src/stm32h5/stm32_pulsecount.h
deleted file mode 100644
index e236340ff62..00000000000
--- a/arch/arm/src/stm32h5/stm32_pulsecount.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/****************************************************************************
- * arch/arm/src/stm32h5/stm32_pulsecount.h
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-#ifndef __ARCH_ARM_SRC_STM32H5_STM32_PULSECOUNT_H
-#define __ARCH_ARM_SRC_STM32H5_STM32_PULSECOUNT_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-#include <nuttx/timers/pulsecount.h>
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-struct pulsecount_lowerhalf_s *stm32_pulsecountinitialize(int timer);
-
-#endif /* __ARCH_ARM_SRC_STM32H5_STM32_PULSECOUNT_H */
diff --git a/arch/arm/src/stm32h7/CMakeLists.txt 
b/arch/arm/src/stm32h7/CMakeLists.txt
index 5f6e1f9800f..79651690179 100644
--- a/arch/arm/src/stm32h7/CMakeLists.txt
+++ b/arch/arm/src/stm32h7/CMakeLists.txt
@@ -184,10 +184,6 @@ if(CONFIG_STM32_PWM)
   list(APPEND SRCS stm32_pwm.c)
 endif()
 
-if(CONFIG_PULSECOUNT)
-  list(APPEND SRCS stm32_pulsecount.c)
-endif()
-
 if(CONFIG_STM32_ETHMAC)
   list(APPEND SRCS stm32_ethernet.c)
 endif()
diff --git a/arch/arm/src/stm32h7/Make.defs b/arch/arm/src/stm32h7/Make.defs
index 298f6da5b5c..e1f6fd958b9 100644
--- a/arch/arm/src/stm32h7/Make.defs
+++ b/arch/arm/src/stm32h7/Make.defs
@@ -183,10 +183,6 @@ ifeq ($(CONFIG_STM32_PWM),y)
 CHIP_CSRCS += stm32_pwm.c
 endif
 
-ifeq ($(CONFIG_STM32_PULSECOUNT),y)
-CHIP_CSRCS += stm32_pulsecount.c
-endif
-
 ifeq ($(CONFIG_STM32_ETHMAC),y)
 CHIP_CSRCS += stm32_ethernet.c
 endif
diff --git a/arch/arm/src/stm32h7/stm32.h b/arch/arm/src/stm32h7/stm32.h
index fa614de2da3..a6d99c17743 100644
--- a/arch/arm/src/stm32h7/stm32.h
+++ b/arch/arm/src/stm32h7/stm32.h
@@ -43,6 +43,7 @@
 #include "stm32_i2c.h"
 #include "stm32_spi.h"
 #include "stm32_rcc.h"
+#include "stm32_tim.h"
 #include "stm32_lowputc.h"
 
 #endif /* __ARCH_ARM_SRC_STM32H7_STM32_H */
diff --git a/arch/arm/src/stm32h7/stm32_pulsecount.h 
b/arch/arm/src/stm32h7/stm32_pulsecount.h
deleted file mode 100644
index efd73aa4a78..00000000000
--- a/arch/arm/src/stm32h7/stm32_pulsecount.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/****************************************************************************
- * arch/arm/src/stm32h7/stm32_pulsecount.h
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-#ifndef __ARCH_ARM_SRC_STM32H7_STM32_PULSECOUNT_H
-#define __ARCH_ARM_SRC_STM32H7_STM32_PULSECOUNT_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-#include <nuttx/timers/pulsecount.h>
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-struct pulsecount_lowerhalf_s *stm32_pulsecountinitialize(int timer);
-
-#endif /* __ARCH_ARM_SRC_STM32H7_STM32_PULSECOUNT_H */
diff --git a/arch/arm/src/stm32l0/stm32.h b/arch/arm/src/stm32l0/stm32.h
index cdcdb2d4aa7..5b77af6b01b 100644
--- a/arch/arm/src/stm32l0/stm32.h
+++ b/arch/arm/src/stm32l0/stm32.h
@@ -43,6 +43,7 @@
 #include "stm32_pwr.h"
 #include "stm32_rcc.h"
 #include "stm32_spi.h"
+#include "stm32_tim.h"
 #include "stm32_uart.h"
 #include "stm32_lowputc.h"
 #include "stm32_adc.h"
diff --git a/arch/arm/src/stm32l4/CMakeLists.txt 
b/arch/arm/src/stm32l4/CMakeLists.txt
index 9ea2ec8809a..0d2406e4095 100644
--- a/arch/arm/src/stm32l4/CMakeLists.txt
+++ b/arch/arm/src/stm32l4/CMakeLists.txt
@@ -162,10 +162,6 @@ if(CONFIG_STM32_PWM)
   list(APPEND SRCS stm32l4_pwm.c)
 endif()
 
-if(CONFIG_PULSECOUNT)
-  list(APPEND SRCS stm32l4_pulsecount.c)
-endif()
-
 if(CONFIG_SENSORS_QENCODER)
   list(APPEND SRCS stm32l4_qencoder.c)
 endif()
diff --git a/arch/arm/src/stm32l4/Make.defs b/arch/arm/src/stm32l4/Make.defs
index 8149af37b75..d62701c5fc4 100644
--- a/arch/arm/src/stm32l4/Make.defs
+++ b/arch/arm/src/stm32l4/Make.defs
@@ -158,10 +158,6 @@ ifeq ($(CONFIG_STM32_PWM),y)
 CHIP_CSRCS += stm32l4_pwm.c
 endif
 
-ifeq ($(CONFIG_STM32_PULSECOUNT),y)
-CHIP_CSRCS += stm32l4_pulsecount.c
-endif
-
 ifeq ($(CONFIG_SENSORS_QENCODER),y)
 CHIP_CSRCS += stm32l4_qencoder.c
 endif
diff --git a/arch/arm/src/stm32l4/stm32l4_pulsecount.h 
b/arch/arm/src/stm32l4/stm32l4_pulsecount.h
deleted file mode 100644
index fc4ee3ed929..00000000000
--- a/arch/arm/src/stm32l4/stm32l4_pulsecount.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/****************************************************************************
- * arch/arm/src/stm32l4/stm32l4_pulsecount.h
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-#ifndef __ARCH_ARM_SRC_STM32L4_STM32L4_PULSECOUNT_H
-#define __ARCH_ARM_SRC_STM32L4_STM32L4_PULSECOUNT_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-#include <nuttx/timers/pulsecount.h>
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-struct pulsecount_lowerhalf_s *stm32_pulsecountinitialize(int timer);
-
-#endif /* __ARCH_ARM_SRC_STM32L4_STM32L4_PULSECOUNT_H */

Reply via email to