You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2022/10/16 15:26:26 UTC

[GitHub] [incubator-nuttx] acassis opened a new pull request, #7328: esp32: Add support to Quadrature Encoder

acassis opened a new pull request, #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328

   ## Summary
   Add support to Quadrature Encoder
   ## Impact
   Users will be able to use QE and Rotary Encoder with NuttX on ESP32
   ## Testing
   esp32-devkitc
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] acassis commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996477811


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {1,2,3,4,5,6,7,8} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t) (getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + (int32_t) count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", pcnt);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse)
+    {
+      snerr("ERROR: PCNT%d is in-use\n", pcnt);
+      return -EBUSY;
+    }
+
+  /* Register the upper-half driver */
+
+  ret = qe_register(devpath, (struct qe_lowerhalf_s *)priv);

Review Comment:
   Ok, I will keep it too. All other qe_register() is using that way.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] acassis commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r997024954


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)

Review Comment:
   No, it is from original file used as base, I will remove them!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] acassis commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996477851


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {1,2,3,4,5,6,7,8} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t) (getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + (int32_t) count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", pcnt);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse)
+    {
+      snerr("ERROR: PCNT%d is in-use\n", pcnt);
+      return -EBUSY;
+    }
+
+  /* Register the upper-half driver */
+
+  ret = qe_register(devpath, (struct qe_lowerhalf_s *)priv);

Review Comment:
   Ditto



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] pkarashchenko commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996489621


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", pcnt);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse)
+    {
+      snerr("ERROR: PCNT%d is in-use\n", pcnt);
+      return -EBUSY;
+    }
+
+  /* Register the upper-half driver */
+
+  ret = qe_register(devpath, (struct qe_lowerhalf_s *)priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: qe_register failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Make sure that the PCNT is in the shutdown state */
+
+  esp32_shutdown((struct qe_lowerhalf_s *)priv);
+
+  /* The driver is now in-use */
+
+  priv->inuse = true;
+
+  return OK;
+}
+
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+/****************************************************************************
+ * Name: esp32_qe_index_init
+ *
+ * Description:
+ *   Register the encoder index pin to a given Qencoder timer
+ *
+ * Input Parameters:
+ *   tim  - The qenco timer number
+ *   gpio - gpio pin configuration
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qe_index_init(int tim, uint32_t gpio)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret = OK;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(tim);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", tim);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse == false)
+    {
+      snerr("ERROR: PCNT%d is not in-use\n", tim);
+      ret = -EINVAL;

Review Comment:
   This is not addressed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] gustavonihei commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
gustavonihei commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r997057004


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif

Review Comment:
   Better remove disabled code.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] pkarashchenko commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996486673


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", pcnt);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse)
+    {
+      snerr("ERROR: PCNT%d is in-use\n", pcnt);
+      return -EBUSY;
+    }
+
+  /* Register the upper-half driver */
+
+  ret = qe_register(devpath, (struct qe_lowerhalf_s *)priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: qe_register failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Make sure that the PCNT is in the shutdown state */
+
+  esp32_shutdown((struct qe_lowerhalf_s *)priv);
+
+  /* The driver is now in-use */
+
+  priv->inuse = true;
+
+  return OK;
+}
+
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+/****************************************************************************
+ * Name: esp32_qe_index_init
+ *
+ * Description:
+ *   Register the encoder index pin to a given Qencoder timer
+ *
+ * Input Parameters:
+ *   tim  - The qenco timer number
+ *   gpio - gpio pin configuration
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qe_index_init(int tim, uint32_t gpio)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret = OK;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(tim);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", tim);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse == false)
+    {
+      snerr("ERROR: PCNT%d is not in-use\n", tim);
+      ret = -EINVAL;

Review Comment:
   will be overwritten by `esp32_gpiosetevent` call below



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)

Review Comment:
   ```suggestion
     if (!priv->index_use)
   ```



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", pcnt);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse)
+    {
+      snerr("ERROR: PCNT%d is in-use\n", pcnt);
+      return -EBUSY;
+    }
+
+  /* Register the upper-half driver */
+
+  ret = qe_register(devpath, (struct qe_lowerhalf_s *)priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: qe_register failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Make sure that the PCNT is in the shutdown state */
+
+  esp32_shutdown((struct qe_lowerhalf_s *)priv);
+
+  /* The driver is now in-use */
+
+  priv->inuse = true;
+
+  return OK;
+}
+
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+/****************************************************************************
+ * Name: esp32_qe_index_init
+ *
+ * Description:
+ *   Register the encoder index pin to a given Qencoder timer
+ *
+ * Input Parameters:
+ *   tim  - The qenco timer number
+ *   gpio - gpio pin configuration
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qe_index_init(int tim, uint32_t gpio)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret = OK;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(tim);
+  if (!priv)

Review Comment:
   optional
   ```suggestion
     if (priv == NULL)
   ```



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", pcnt);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse)
+    {
+      snerr("ERROR: PCNT%d is in-use\n", pcnt);
+      return -EBUSY;
+    }
+
+  /* Register the upper-half driver */
+
+  ret = qe_register(devpath, (struct qe_lowerhalf_s *)priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: qe_register failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Make sure that the PCNT is in the shutdown state */
+
+  esp32_shutdown((struct qe_lowerhalf_s *)priv);
+
+  /* The driver is now in-use */
+
+  priv->inuse = true;
+
+  return OK;
+}
+
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+/****************************************************************************
+ * Name: esp32_qe_index_init
+ *
+ * Description:
+ *   Register the encoder index pin to a given Qencoder timer
+ *
+ * Input Parameters:
+ *   tim  - The qenco timer number
+ *   gpio - gpio pin configuration
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qe_index_init(int tim, uint32_t gpio)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret = OK;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(tim);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", tim);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse == false)

Review Comment:
   ```suggestion
     if (!priv->inuse)
   ```



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", pcnt);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse)
+    {
+      snerr("ERROR: PCNT%d is in-use\n", pcnt);
+      return -EBUSY;
+    }
+
+  /* Register the upper-half driver */
+
+  ret = qe_register(devpath, (struct qe_lowerhalf_s *)priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: qe_register failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Make sure that the PCNT is in the shutdown state */
+
+  esp32_shutdown((struct qe_lowerhalf_s *)priv);
+
+  /* The driver is now in-use */
+
+  priv->inuse = true;
+
+  return OK;
+}
+
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+/****************************************************************************
+ * Name: esp32_qe_index_init
+ *
+ * Description:
+ *   Register the encoder index pin to a given Qencoder timer
+ *
+ * Input Parameters:
+ *   tim  - The qenco timer number
+ *   gpio - gpio pin configuration
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qe_index_init(int tim, uint32_t gpio)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret = OK;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(tim);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", tim);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse == false)
+    {
+      snerr("ERROR: PCNT%d is not in-use\n", tim);
+      ret = -EINVAL;
+    }
+
+  /* Configure QE index pin */
+
+  priv->index_pin = gpio;

Review Comment:
   somehow I fail to find `index_pin` in `struct esp32_lowerhalf_s`



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)

Review Comment:
   Optional
   ```suggestion
     if (priv == NULL)
   ```



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", pcnt);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse)
+    {
+      snerr("ERROR: PCNT%d is in-use\n", pcnt);
+      return -EBUSY;
+    }
+
+  /* Register the upper-half driver */
+
+  ret = qe_register(devpath, (struct qe_lowerhalf_s *)priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: qe_register failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Make sure that the PCNT is in the shutdown state */
+
+  esp32_shutdown((struct qe_lowerhalf_s *)priv);
+
+  /* The driver is now in-use */
+
+  priv->inuse = true;
+
+  return OK;
+}
+
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+/****************************************************************************
+ * Name: esp32_qe_index_init
+ *
+ * Description:
+ *   Register the encoder index pin to a given Qencoder timer
+ *
+ * Input Parameters:
+ *   tim  - The qenco timer number
+ *   gpio - gpio pin configuration
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qe_index_init(int tim, uint32_t gpio)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret = OK;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(tim);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", tim);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse == false)
+    {
+      snerr("ERROR: PCNT%d is not in-use\n", tim);
+      ret = -EINVAL;
+    }
+
+  /* Configure QE index pin */
+
+  priv->index_pin = gpio;
+  esp32_configgpio(priv->index_pin);
+
+  /* Register interrupt */
+
+  ret = esp32_gpiosetevent(gpio, true, false, true,
+                           esp32_qe_index_irq, priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: QE PCNT%d failed register irq\n", tim);
+      goto errout;
+    }
+
+  /* Set flag */
+
+  priv->index_use = true;

Review Comment:
   somehow I fail to find `index_use` in `struct esp32_lowerhalf_s`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] acassis commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996489606


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", pcnt);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse)
+    {
+      snerr("ERROR: PCNT%d is in-use\n", pcnt);
+      return -EBUSY;
+    }
+
+  /* Register the upper-half driver */
+
+  ret = qe_register(devpath, (struct qe_lowerhalf_s *)priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: qe_register failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Make sure that the PCNT is in the shutdown state */
+
+  esp32_shutdown((struct qe_lowerhalf_s *)priv);
+
+  /* The driver is now in-use */
+
+  priv->inuse = true;
+
+  return OK;
+}
+
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+/****************************************************************************
+ * Name: esp32_qe_index_init
+ *
+ * Description:
+ *   Register the encoder index pin to a given Qencoder timer
+ *
+ * Input Parameters:
+ *   tim  - The qenco timer number
+ *   gpio - gpio pin configuration
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qe_index_init(int tim, uint32_t gpio)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret = OK;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(tim);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", tim);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse == false)
+    {
+      snerr("ERROR: PCNT%d is not in-use\n", tim);
+      ret = -EINVAL;

Review Comment:
   Removed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] pkarashchenko commented on pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#issuecomment-1280048558

   Please ping me when all changes are applied. Also please squash commints


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] acassis commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r997024199


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)

Review Comment:
   These configs come from original stm32_qencoder.c that I used as base!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] tmedicci commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
tmedicci commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996992287


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,

Review Comment:
   Formating: `=` are not aligned



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] tmedicci commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
tmedicci commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996990918


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */

Review Comment:
   typo: `/* FIXME: To be implemented */`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] acassis commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996477213


##########
arch/xtensa/src/esp32/hardware/esp32_pcnt.h:
##########
@@ -0,0 +1,2495 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/hardware/esp32_pcnt.h
+ *
+ * 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_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+#define __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* PCNT_U0_CONF0_REG register
+ * Configuration register 0 for unit 0
+ */
+
+#define PCNT_U0_CONF0_REG (DR_REG_PCNT_BASE + 0x0)
+
+/* PCNT_CH1_LCTRL_MODE_U0 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_M  (PCNT_CH1_LCTRL_MODE_U0_V << PCNT_CH1_LCTRL_MODE_U0_S)
+#define PCNT_CH1_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U0 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_M  (PCNT_CH1_HCTRL_MODE_U0_V << PCNT_CH1_HCTRL_MODE_U0_S)
+#define PCNT_CH1_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_S  28
+
+/* PCNT_CH1_POS_MODE_U0 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U0    0x00000003
+#define PCNT_CH1_POS_MODE_U0_M  (PCNT_CH1_POS_MODE_U0_V << PCNT_CH1_POS_MODE_U0_S)
+#define PCNT_CH1_POS_MODE_U0_V  0x00000003
+#define PCNT_CH1_POS_MODE_U0_S  26
+
+/* PCNT_CH1_NEG_MODE_U0 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U0    0x00000003
+#define PCNT_CH1_NEG_MODE_U0_M  (PCNT_CH1_NEG_MODE_U0_V << PCNT_CH1_NEG_MODE_U0_S)
+#define PCNT_CH1_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U0_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U0 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_M  (PCNT_CH0_LCTRL_MODE_U0_V << PCNT_CH0_LCTRL_MODE_U0_S)
+#define PCNT_CH0_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U0 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_M  (PCNT_CH0_HCTRL_MODE_U0_V << PCNT_CH0_HCTRL_MODE_U0_S)
+#define PCNT_CH0_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_S  20
+
+/* PCNT_CH0_POS_MODE_U0 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U0    0x00000003
+#define PCNT_CH0_POS_MODE_U0_M  (PCNT_CH0_POS_MODE_U0_V << PCNT_CH0_POS_MODE_U0_S)
+#define PCNT_CH0_POS_MODE_U0_V  0x00000003
+#define PCNT_CH0_POS_MODE_U0_S  18
+
+/* PCNT_CH0_NEG_MODE_U0 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U0    0x00000003
+#define PCNT_CH0_NEG_MODE_U0_M  (PCNT_CH0_NEG_MODE_U0_V << PCNT_CH0_NEG_MODE_U0_S)
+#define PCNT_CH0_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U0_S  16
+
+/* PCNT_THR_THRES1_EN_U0 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 0's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U0    (BIT(15))
+#define PCNT_THR_THRES1_EN_U0_M  (PCNT_THR_THRES1_EN_U0_V << PCNT_THR_THRES1_EN_U0_S)
+#define PCNT_THR_THRES1_EN_U0_V  0x00000001
+#define PCNT_THR_THRES1_EN_U0_S  15
+
+/* PCNT_THR_THRES0_EN_U0 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 0's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U0    (BIT(14))
+#define PCNT_THR_THRES0_EN_U0_M  (PCNT_THR_THRES0_EN_U0_V << PCNT_THR_THRES0_EN_U0_S)
+#define PCNT_THR_THRES0_EN_U0_V  0x00000001
+#define PCNT_THR_THRES0_EN_U0_S  14
+
+/* PCNT_THR_L_LIM_EN_U0 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 0's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U0    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U0_M  (PCNT_THR_L_LIM_EN_U0_V << PCNT_THR_L_LIM_EN_U0_S)
+#define PCNT_THR_L_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U0_S  13
+
+/* PCNT_THR_H_LIM_EN_U0 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 0's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U0    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U0_M  (PCNT_THR_H_LIM_EN_U0_V << PCNT_THR_H_LIM_EN_U0_S)
+#define PCNT_THR_H_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U0_S  12
+
+/* PCNT_THR_ZERO_EN_U0 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 0's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U0    (BIT(11))
+#define PCNT_THR_ZERO_EN_U0_M  (PCNT_THR_ZERO_EN_U0_V << PCNT_THR_ZERO_EN_U0_S)
+#define PCNT_THR_ZERO_EN_U0_V  0x00000001
+#define PCNT_THR_ZERO_EN_U0_S  11
+
+/* PCNT_FILTER_EN_U0 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 0's input filter.
+ */
+
+#define PCNT_FILTER_EN_U0    (BIT(10))
+#define PCNT_FILTER_EN_U0_M  (PCNT_FILTER_EN_U0_V << PCNT_FILTER_EN_U0_S)
+#define PCNT_FILTER_EN_U0_V  0x00000001
+#define PCNT_FILTER_EN_U0_S  10
+
+/* PCNT_FILTER_THRES_U0 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U0    0x000003ff
+#define PCNT_FILTER_THRES_U0_M  (PCNT_FILTER_THRES_U0_V << PCNT_FILTER_THRES_U0_S)
+#define PCNT_FILTER_THRES_U0_V  0x000003ff
+#define PCNT_FILTER_THRES_U0_S  0
+
+/* PCNT_U0_CONF1_REG register
+ * Configuration register 1 for unit 0
+ */
+
+#define PCNT_U0_CONF1_REG (DR_REG_PCNT_BASE + 0x4)
+
+/* PCNT_CNT_THRES1_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES1_U0    0x0000ffff
+#define PCNT_CNT_THRES1_U0_M  (PCNT_CNT_THRES1_U0_V << PCNT_CNT_THRES1_U0_S)
+#define PCNT_CNT_THRES1_U0_V  0x0000ffff
+#define PCNT_CNT_THRES1_U0_S  16
+
+/* PCNT_CNT_THRES0_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES0_U0    0x0000ffff
+#define PCNT_CNT_THRES0_U0_M  (PCNT_CNT_THRES0_U0_V << PCNT_CNT_THRES0_U0_S)
+#define PCNT_CNT_THRES0_U0_V  0x0000ffff
+#define PCNT_CNT_THRES0_U0_S  0
+
+/* PCNT_U0_CONF2_REG register
+ * Configuration register 2 for unit 0
+ */
+
+#define PCNT_U0_CONF2_REG (DR_REG_PCNT_BASE + 0x8)
+
+/* PCNT_CNT_L_LIM_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 0.
+ */
+
+#define PCNT_CNT_L_LIM_U0    0x0000ffff
+#define PCNT_CNT_L_LIM_U0_M  (PCNT_CNT_L_LIM_U0_V << PCNT_CNT_L_LIM_U0_S)
+#define PCNT_CNT_L_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U0_S  16
+
+/* PCNT_CNT_H_LIM_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 0.
+ */
+
+#define PCNT_CNT_H_LIM_U0    0x0000ffff
+#define PCNT_CNT_H_LIM_U0_M  (PCNT_CNT_H_LIM_U0_V << PCNT_CNT_H_LIM_U0_S)
+#define PCNT_CNT_H_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U0_S  0
+
+/* PCNT_U1_CONF0_REG register
+ * Configuration register 0 for unit 1
+ */
+
+#define PCNT_U1_CONF0_REG (DR_REG_PCNT_BASE + 0xc)
+
+/* PCNT_CH1_LCTRL_MODE_U1 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_M  (PCNT_CH1_LCTRL_MODE_U1_V << PCNT_CH1_LCTRL_MODE_U1_S)
+#define PCNT_CH1_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U1 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_M  (PCNT_CH1_HCTRL_MODE_U1_V << PCNT_CH1_HCTRL_MODE_U1_S)
+#define PCNT_CH1_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_S  28
+
+/* PCNT_CH1_POS_MODE_U1 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U1    0x00000003
+#define PCNT_CH1_POS_MODE_U1_M  (PCNT_CH1_POS_MODE_U1_V << PCNT_CH1_POS_MODE_U1_S)
+#define PCNT_CH1_POS_MODE_U1_V  0x00000003
+#define PCNT_CH1_POS_MODE_U1_S  26
+
+/* PCNT_CH1_NEG_MODE_U1 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U1    0x00000003
+#define PCNT_CH1_NEG_MODE_U1_M  (PCNT_CH1_NEG_MODE_U1_V << PCNT_CH1_NEG_MODE_U1_S)
+#define PCNT_CH1_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U1_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U1 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_M  (PCNT_CH0_LCTRL_MODE_U1_V << PCNT_CH0_LCTRL_MODE_U1_S)
+#define PCNT_CH0_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U1 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_M  (PCNT_CH0_HCTRL_MODE_U1_V << PCNT_CH0_HCTRL_MODE_U1_S)
+#define PCNT_CH0_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_S  20
+
+/* PCNT_CH0_POS_MODE_U1 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U1    0x00000003
+#define PCNT_CH0_POS_MODE_U1_M  (PCNT_CH0_POS_MODE_U1_V << PCNT_CH0_POS_MODE_U1_S)
+#define PCNT_CH0_POS_MODE_U1_V  0x00000003
+#define PCNT_CH0_POS_MODE_U1_S  18
+
+/* PCNT_CH0_NEG_MODE_U1 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U1    0x00000003
+#define PCNT_CH0_NEG_MODE_U1_M  (PCNT_CH0_NEG_MODE_U1_V << PCNT_CH0_NEG_MODE_U1_S)
+#define PCNT_CH0_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U1_S  16
+
+/* PCNT_THR_THRES1_EN_U1 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 1's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U1    (BIT(15))
+#define PCNT_THR_THRES1_EN_U1_M  (PCNT_THR_THRES1_EN_U1_V << PCNT_THR_THRES1_EN_U1_S)
+#define PCNT_THR_THRES1_EN_U1_V  0x00000001
+#define PCNT_THR_THRES1_EN_U1_S  15
+
+/* PCNT_THR_THRES0_EN_U1 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 1's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U1    (BIT(14))
+#define PCNT_THR_THRES0_EN_U1_M  (PCNT_THR_THRES0_EN_U1_V << PCNT_THR_THRES0_EN_U1_S)
+#define PCNT_THR_THRES0_EN_U1_V  0x00000001
+#define PCNT_THR_THRES0_EN_U1_S  14
+
+/* PCNT_THR_L_LIM_EN_U1 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 1's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U1    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U1_M  (PCNT_THR_L_LIM_EN_U1_V << PCNT_THR_L_LIM_EN_U1_S)
+#define PCNT_THR_L_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U1_S  13
+
+/* PCNT_THR_H_LIM_EN_U1 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 1's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U1    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U1_M  (PCNT_THR_H_LIM_EN_U1_V << PCNT_THR_H_LIM_EN_U1_S)
+#define PCNT_THR_H_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U1_S  12
+
+/* PCNT_THR_ZERO_EN_U1 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 1's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U1    (BIT(11))
+#define PCNT_THR_ZERO_EN_U1_M  (PCNT_THR_ZERO_EN_U1_V << PCNT_THR_ZERO_EN_U1_S)
+#define PCNT_THR_ZERO_EN_U1_V  0x00000001
+#define PCNT_THR_ZERO_EN_U1_S  11
+
+/* PCNT_FILTER_EN_U1 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 1's input filter.
+ */
+
+#define PCNT_FILTER_EN_U1    (BIT(10))
+#define PCNT_FILTER_EN_U1_M  (PCNT_FILTER_EN_U1_V << PCNT_FILTER_EN_U1_S)
+#define PCNT_FILTER_EN_U1_V  0x00000001
+#define PCNT_FILTER_EN_U1_S  10
+
+/* PCNT_FILTER_THRES_U1 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U1    0x000003ff
+#define PCNT_FILTER_THRES_U1_M  (PCNT_FILTER_THRES_U1_V << PCNT_FILTER_THRES_U1_S)
+#define PCNT_FILTER_THRES_U1_V  0x000003ff
+#define PCNT_FILTER_THRES_U1_S  0
+
+/* PCNT_U1_CONF1_REG register
+ * Configuration register 1 for unit 1
+ */
+
+#define PCNT_U1_CONF1_REG (DR_REG_PCNT_BASE + 0x10)
+
+/* PCNT_CNT_THRES1_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES1_U1    0x0000ffff
+#define PCNT_CNT_THRES1_U1_M  (PCNT_CNT_THRES1_U1_V << PCNT_CNT_THRES1_U1_S)
+#define PCNT_CNT_THRES1_U1_V  0x0000ffff
+#define PCNT_CNT_THRES1_U1_S  16
+
+/* PCNT_CNT_THRES0_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES0_U1    0x0000ffff
+#define PCNT_CNT_THRES0_U1_M  (PCNT_CNT_THRES0_U1_V << PCNT_CNT_THRES0_U1_S)
+#define PCNT_CNT_THRES0_U1_V  0x0000ffff
+#define PCNT_CNT_THRES0_U1_S  0
+
+/* PCNT_U1_CONF2_REG register
+ * Configuration register 2 for unit 1
+ */
+
+#define PCNT_U1_CONF2_REG (DR_REG_PCNT_BASE + 0x14)
+
+/* PCNT_CNT_L_LIM_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 1.
+ */
+
+#define PCNT_CNT_L_LIM_U1    0x0000ffff
+#define PCNT_CNT_L_LIM_U1_M  (PCNT_CNT_L_LIM_U1_V << PCNT_CNT_L_LIM_U1_S)
+#define PCNT_CNT_L_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U1_S  16
+
+/* PCNT_CNT_H_LIM_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 1.
+ */
+
+#define PCNT_CNT_H_LIM_U1    0x0000ffff
+#define PCNT_CNT_H_LIM_U1_M  (PCNT_CNT_H_LIM_U1_V << PCNT_CNT_H_LIM_U1_S)
+#define PCNT_CNT_H_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U1_S  0
+
+/* PCNT_U2_CONF0_REG register
+ * Configuration register 0 for unit 2
+ */
+
+#define PCNT_U2_CONF0_REG (DR_REG_PCNT_BASE + 0x18)
+
+/* PCNT_CH1_LCTRL_MODE_U2 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_M  (PCNT_CH1_LCTRL_MODE_U2_V << PCNT_CH1_LCTRL_MODE_U2_S)
+#define PCNT_CH1_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U2 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_M  (PCNT_CH1_HCTRL_MODE_U2_V << PCNT_CH1_HCTRL_MODE_U2_S)
+#define PCNT_CH1_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_S  28
+
+/* PCNT_CH1_POS_MODE_U2 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U2    0x00000003
+#define PCNT_CH1_POS_MODE_U2_M  (PCNT_CH1_POS_MODE_U2_V << PCNT_CH1_POS_MODE_U2_S)
+#define PCNT_CH1_POS_MODE_U2_V  0x00000003
+#define PCNT_CH1_POS_MODE_U2_S  26
+
+/* PCNT_CH1_NEG_MODE_U2 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U2    0x00000003
+#define PCNT_CH1_NEG_MODE_U2_M  (PCNT_CH1_NEG_MODE_U2_V << PCNT_CH1_NEG_MODE_U2_S)
+#define PCNT_CH1_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U2_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U2 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_M  (PCNT_CH0_LCTRL_MODE_U2_V << PCNT_CH0_LCTRL_MODE_U2_S)
+#define PCNT_CH0_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U2 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_M  (PCNT_CH0_HCTRL_MODE_U2_V << PCNT_CH0_HCTRL_MODE_U2_S)
+#define PCNT_CH0_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_S  20
+
+/* PCNT_CH0_POS_MODE_U2 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U2    0x00000003
+#define PCNT_CH0_POS_MODE_U2_M  (PCNT_CH0_POS_MODE_U2_V << PCNT_CH0_POS_MODE_U2_S)
+#define PCNT_CH0_POS_MODE_U2_V  0x00000003
+#define PCNT_CH0_POS_MODE_U2_S  18
+
+/* PCNT_CH0_NEG_MODE_U2 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U2    0x00000003
+#define PCNT_CH0_NEG_MODE_U2_M  (PCNT_CH0_NEG_MODE_U2_V << PCNT_CH0_NEG_MODE_U2_S)
+#define PCNT_CH0_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U2_S  16
+
+/* PCNT_THR_THRES1_EN_U2 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 2's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U2    (BIT(15))
+#define PCNT_THR_THRES1_EN_U2_M  (PCNT_THR_THRES1_EN_U2_V << PCNT_THR_THRES1_EN_U2_S)
+#define PCNT_THR_THRES1_EN_U2_V  0x00000001
+#define PCNT_THR_THRES1_EN_U2_S  15
+
+/* PCNT_THR_THRES0_EN_U2 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 2's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U2    (BIT(14))
+#define PCNT_THR_THRES0_EN_U2_M  (PCNT_THR_THRES0_EN_U2_V << PCNT_THR_THRES0_EN_U2_S)
+#define PCNT_THR_THRES0_EN_U2_V  0x00000001
+#define PCNT_THR_THRES0_EN_U2_S  14
+
+/* PCNT_THR_L_LIM_EN_U2 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 2's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U2    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U2_M  (PCNT_THR_L_LIM_EN_U2_V << PCNT_THR_L_LIM_EN_U2_S)
+#define PCNT_THR_L_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U2_S  13
+
+/* PCNT_THR_H_LIM_EN_U2 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 2's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U2    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U2_M  (PCNT_THR_H_LIM_EN_U2_V << PCNT_THR_H_LIM_EN_U2_S)
+#define PCNT_THR_H_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U2_S  12
+
+/* PCNT_THR_ZERO_EN_U2 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 2's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U2    (BIT(11))
+#define PCNT_THR_ZERO_EN_U2_M  (PCNT_THR_ZERO_EN_U2_V << PCNT_THR_ZERO_EN_U2_S)
+#define PCNT_THR_ZERO_EN_U2_V  0x00000001
+#define PCNT_THR_ZERO_EN_U2_S  11
+
+/* PCNT_FILTER_EN_U2 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 2's input filter.
+ */
+
+#define PCNT_FILTER_EN_U2    (BIT(10))
+#define PCNT_FILTER_EN_U2_M  (PCNT_FILTER_EN_U2_V << PCNT_FILTER_EN_U2_S)
+#define PCNT_FILTER_EN_U2_V  0x00000001
+#define PCNT_FILTER_EN_U2_S  10
+
+/* PCNT_FILTER_THRES_U2 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U2    0x000003ff
+#define PCNT_FILTER_THRES_U2_M  (PCNT_FILTER_THRES_U2_V << PCNT_FILTER_THRES_U2_S)
+#define PCNT_FILTER_THRES_U2_V  0x000003ff
+#define PCNT_FILTER_THRES_U2_S  0
+
+/* PCNT_U2_CONF1_REG register
+ * Configuration register 1 for unit 2
+ */
+
+#define PCNT_U2_CONF1_REG (DR_REG_PCNT_BASE + 0x1c)
+
+/* PCNT_CNT_THRES1_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES1_U2    0x0000ffff
+#define PCNT_CNT_THRES1_U2_M  (PCNT_CNT_THRES1_U2_V << PCNT_CNT_THRES1_U2_S)
+#define PCNT_CNT_THRES1_U2_V  0x0000ffff
+#define PCNT_CNT_THRES1_U2_S  16
+
+/* PCNT_CNT_THRES0_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES0_U2    0x0000ffff
+#define PCNT_CNT_THRES0_U2_M  (PCNT_CNT_THRES0_U2_V << PCNT_CNT_THRES0_U2_S)
+#define PCNT_CNT_THRES0_U2_V  0x0000ffff
+#define PCNT_CNT_THRES0_U2_S  0
+
+/* PCNT_U2_CONF2_REG register
+ * Configuration register 2 for unit 2
+ */
+
+#define PCNT_U2_CONF2_REG (DR_REG_PCNT_BASE + 0x20)
+
+/* PCNT_CNT_L_LIM_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 2.
+ */
+
+#define PCNT_CNT_L_LIM_U2    0x0000ffff
+#define PCNT_CNT_L_LIM_U2_M  (PCNT_CNT_L_LIM_U2_V << PCNT_CNT_L_LIM_U2_S)
+#define PCNT_CNT_L_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U2_S  16
+
+/* PCNT_CNT_H_LIM_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 2.
+ */
+
+#define PCNT_CNT_H_LIM_U2    0x0000ffff
+#define PCNT_CNT_H_LIM_U2_M  (PCNT_CNT_H_LIM_U2_V << PCNT_CNT_H_LIM_U2_S)
+#define PCNT_CNT_H_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U2_S  0
+
+/* PCNT_U3_CONF0_REG register
+ * Configuration register 0 for unit 3
+ */
+
+#define PCNT_U3_CONF0_REG (DR_REG_PCNT_BASE + 0x24)
+
+/* PCNT_CH1_LCTRL_MODE_U3 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_M  (PCNT_CH1_LCTRL_MODE_U3_V << PCNT_CH1_LCTRL_MODE_U3_S)
+#define PCNT_CH1_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U3 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_M  (PCNT_CH1_HCTRL_MODE_U3_V << PCNT_CH1_HCTRL_MODE_U3_S)
+#define PCNT_CH1_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_S  28
+
+/* PCNT_CH1_POS_MODE_U3 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U3    0x00000003
+#define PCNT_CH1_POS_MODE_U3_M  (PCNT_CH1_POS_MODE_U3_V << PCNT_CH1_POS_MODE_U3_S)
+#define PCNT_CH1_POS_MODE_U3_V  0x00000003
+#define PCNT_CH1_POS_MODE_U3_S  26
+
+/* PCNT_CH1_NEG_MODE_U3 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U3    0x00000003
+#define PCNT_CH1_NEG_MODE_U3_M  (PCNT_CH1_NEG_MODE_U3_V << PCNT_CH1_NEG_MODE_U3_S)
+#define PCNT_CH1_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U3_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U3 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_M  (PCNT_CH0_LCTRL_MODE_U3_V << PCNT_CH0_LCTRL_MODE_U3_S)
+#define PCNT_CH0_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U3 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_M  (PCNT_CH0_HCTRL_MODE_U3_V << PCNT_CH0_HCTRL_MODE_U3_S)
+#define PCNT_CH0_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_S  20
+
+/* PCNT_CH0_POS_MODE_U3 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U3    0x00000003
+#define PCNT_CH0_POS_MODE_U3_M  (PCNT_CH0_POS_MODE_U3_V << PCNT_CH0_POS_MODE_U3_S)
+#define PCNT_CH0_POS_MODE_U3_V  0x00000003
+#define PCNT_CH0_POS_MODE_U3_S  18
+
+/* PCNT_CH0_NEG_MODE_U3 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U3    0x00000003
+#define PCNT_CH0_NEG_MODE_U3_M  (PCNT_CH0_NEG_MODE_U3_V << PCNT_CH0_NEG_MODE_U3_S)
+#define PCNT_CH0_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U3_S  16
+
+/* PCNT_THR_THRES1_EN_U3 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 3's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U3    (BIT(15))
+#define PCNT_THR_THRES1_EN_U3_M  (PCNT_THR_THRES1_EN_U3_V << PCNT_THR_THRES1_EN_U3_S)
+#define PCNT_THR_THRES1_EN_U3_V  0x00000001
+#define PCNT_THR_THRES1_EN_U3_S  15
+
+/* PCNT_THR_THRES0_EN_U3 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 3's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U3    (BIT(14))
+#define PCNT_THR_THRES0_EN_U3_M  (PCNT_THR_THRES0_EN_U3_V << PCNT_THR_THRES0_EN_U3_S)
+#define PCNT_THR_THRES0_EN_U3_V  0x00000001
+#define PCNT_THR_THRES0_EN_U3_S  14
+
+/* PCNT_THR_L_LIM_EN_U3 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 3's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U3    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U3_M  (PCNT_THR_L_LIM_EN_U3_V << PCNT_THR_L_LIM_EN_U3_S)
+#define PCNT_THR_L_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U3_S  13
+
+/* PCNT_THR_H_LIM_EN_U3 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 3's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U3    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U3_M  (PCNT_THR_H_LIM_EN_U3_V << PCNT_THR_H_LIM_EN_U3_S)
+#define PCNT_THR_H_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U3_S  12
+
+/* PCNT_THR_ZERO_EN_U3 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 3's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U3    (BIT(11))
+#define PCNT_THR_ZERO_EN_U3_M  (PCNT_THR_ZERO_EN_U3_V << PCNT_THR_ZERO_EN_U3_S)
+#define PCNT_THR_ZERO_EN_U3_V  0x00000001
+#define PCNT_THR_ZERO_EN_U3_S  11
+
+/* PCNT_FILTER_EN_U3 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 3's input filter.
+ */
+
+#define PCNT_FILTER_EN_U3    (BIT(10))
+#define PCNT_FILTER_EN_U3_M  (PCNT_FILTER_EN_U3_V << PCNT_FILTER_EN_U3_S)
+#define PCNT_FILTER_EN_U3_V  0x00000001
+#define PCNT_FILTER_EN_U3_S  10
+
+/* PCNT_FILTER_THRES_U3 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U3    0x000003ff
+#define PCNT_FILTER_THRES_U3_M  (PCNT_FILTER_THRES_U3_V << PCNT_FILTER_THRES_U3_S)
+#define PCNT_FILTER_THRES_U3_V  0x000003ff
+#define PCNT_FILTER_THRES_U3_S  0
+
+/* PCNT_U3_CONF1_REG register
+ * Configuration register 1 for unit 3
+ */
+
+#define PCNT_U3_CONF1_REG (DR_REG_PCNT_BASE + 0x28)
+
+/* PCNT_CNT_THRES1_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES1_U3    0x0000ffff
+#define PCNT_CNT_THRES1_U3_M  (PCNT_CNT_THRES1_U3_V << PCNT_CNT_THRES1_U3_S)
+#define PCNT_CNT_THRES1_U3_V  0x0000ffff
+#define PCNT_CNT_THRES1_U3_S  16
+
+/* PCNT_CNT_THRES0_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES0_U3    0x0000ffff
+#define PCNT_CNT_THRES0_U3_M  (PCNT_CNT_THRES0_U3_V << PCNT_CNT_THRES0_U3_S)
+#define PCNT_CNT_THRES0_U3_V  0x0000ffff
+#define PCNT_CNT_THRES0_U3_S  0
+
+/* PCNT_U3_CONF2_REG register
+ * Configuration register 2 for unit 3
+ */
+
+#define PCNT_U3_CONF2_REG (DR_REG_PCNT_BASE + 0x2c)
+
+/* PCNT_CNT_L_LIM_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 3.
+ */
+
+#define PCNT_CNT_L_LIM_U3    0x0000ffff
+#define PCNT_CNT_L_LIM_U3_M  (PCNT_CNT_L_LIM_U3_V << PCNT_CNT_L_LIM_U3_S)
+#define PCNT_CNT_L_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U3_S  16
+
+/* PCNT_CNT_H_LIM_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 3.
+ */
+
+#define PCNT_CNT_H_LIM_U3    0x0000ffff
+#define PCNT_CNT_H_LIM_U3_M  (PCNT_CNT_H_LIM_U3_V << PCNT_CNT_H_LIM_U3_S)
+#define PCNT_CNT_H_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U3_S  0
+
+#define PCNT_U4_CONF0_REG          (DR_REG_PCNT_BASE + 0x0030)
+
+/* PCNT_CH1_LCTRL_MODE_U4 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U4_M  ((PCNT_CH1_LCTRL_MODE_U4_V)<<(PCNT_CH1_LCTRL_MODE_U4_S))
+#define PCNT_CH1_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U4_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U4 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U4_M  ((PCNT_CH1_HCTRL_MODE_U4_V)<<(PCNT_CH1_HCTRL_MODE_U4_S))
+#define PCNT_CH1_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U4_S  28
+
+/* PCNT_CH1_POS_MODE_U4 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U4  0x00000003
+#define PCNT_CH1_POS_MODE_U4_M  ((PCNT_CH1_POS_MODE_U4_V)<<(PCNT_CH1_POS_MODE_U4_S))
+#define PCNT_CH1_POS_MODE_U4_V  0x3
+#define PCNT_CH1_POS_MODE_U4_S  26
+
+/* PCNT_CH1_NEG_MODE_U4 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U4  0x00000003
+#define PCNT_CH1_NEG_MODE_U4_M  ((PCNT_CH1_NEG_MODE_U4_V)<<(PCNT_CH1_NEG_MODE_U4_S))
+#define PCNT_CH1_NEG_MODE_U4_V  0x3
+#define PCNT_CH1_NEG_MODE_U4_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U4 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U4_M  ((PCNT_CH0_LCTRL_MODE_U4_V)<<(PCNT_CH0_LCTRL_MODE_U4_S))
+#define PCNT_CH0_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U4_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U4 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U4_M  ((PCNT_CH0_HCTRL_MODE_U4_V)<<(PCNT_CH0_HCTRL_MODE_U4_S))
+#define PCNT_CH0_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U4_S  20
+
+/* PCNT_CH0_POS_MODE_U4 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U4  0x00000003
+#define PCNT_CH0_POS_MODE_U4_M  ((PCNT_CH0_POS_MODE_U4_V)<<(PCNT_CH0_POS_MODE_U4_S))
+#define PCNT_CH0_POS_MODE_U4_V  0x3
+#define PCNT_CH0_POS_MODE_U4_S  18
+
+/* PCNT_CH0_NEG_MODE_U4 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U4  0x00000003
+#define PCNT_CH0_NEG_MODE_U4_M  ((PCNT_CH0_NEG_MODE_U4_V)<<(PCNT_CH0_NEG_MODE_U4_S))
+#define PCNT_CH0_NEG_MODE_U4_V  0x3
+#define PCNT_CH0_NEG_MODE_U4_S  16
+
+/* PCNT_THR_THRES1_EN_U4 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U4  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_V  0x1
+#define PCNT_THR_THRES1_EN_U4_S  15
+
+/* PCNT_THR_THRES0_EN_U4 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U4  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_V  0x1
+#define PCNT_THR_THRES0_EN_U4_S  14
+
+/* PCNT_THR_L_LIM_EN_U4 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_l_lim  value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U4  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_V  0x1
+#define PCNT_THR_L_LIM_EN_U4_S  13
+
+/* PCNT_THR_H_LIM_EN_U4 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U4  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_V  0x1
+#define PCNT_THR_H_LIM_EN_U4_S  12
+
+/* PCNT_THR_ZERO_EN_U4 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U4  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_V  0x1
+#define PCNT_THR_ZERO_EN_U4_S  11
+
+/* PCNT_FILTER_EN_U4 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit4.
+ */
+
+#define PCNT_FILTER_EN_U4  (BIT(10))
+#define PCNT_FILTER_EN_U4_M  (BIT(10))
+#define PCNT_FILTER_EN_U4_V  0x1
+#define PCNT_FILTER_EN_U4_S  10
+
+/* PCNT_FILTER_THRES_U4 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit4.
+ */
+
+#define PCNT_FILTER_THRES_U4  0x000003FF
+#define PCNT_FILTER_THRES_U4_M  ((PCNT_FILTER_THRES_U4_V)<<(PCNT_FILTER_THRES_U4_S))
+#define PCNT_FILTER_THRES_U4_V  0x3FF
+#define PCNT_FILTER_THRES_U4_S  0
+
+#define PCNT_U4_CONF1_REG          (DR_REG_PCNT_BASE + 0x0034)
+
+/* PCNT_CNT_THRES1_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure thres1 value for unit4.
+ */
+
+#define PCNT_CNT_THRES1_U4  0x0000FFFF
+#define PCNT_CNT_THRES1_U4_M  ((PCNT_CNT_THRES1_U4_V)<<(PCNT_CNT_THRES1_U4_S))
+#define PCNT_CNT_THRES1_U4_V  0xFFFF
+#define PCNT_CNT_THRES1_U4_S  16
+
+/* PCNT_CNT_THRES0_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit4.
+ */
+
+#define PCNT_CNT_THRES0_U4  0x0000FFFF
+#define PCNT_CNT_THRES0_U4_M  ((PCNT_CNT_THRES0_U4_V)<<(PCNT_CNT_THRES0_U4_S))
+#define PCNT_CNT_THRES0_U4_V  0xFFFF
+#define PCNT_CNT_THRES0_U4_S  0
+
+#define PCNT_U4_CONF2_REG          (DR_REG_PCNT_BASE + 0x0038)
+
+/* PCNT_CNT_L_LIM_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit4.
+ */
+
+#define PCNT_CNT_L_LIM_U4  0x0000FFFF
+#define PCNT_CNT_L_LIM_U4_M  ((PCNT_CNT_L_LIM_U4_V)<<(PCNT_CNT_L_LIM_U4_S))
+#define PCNT_CNT_L_LIM_U4_V  0xFFFF
+#define PCNT_CNT_L_LIM_U4_S  16
+
+/* PCNT_CNT_H_LIM_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit4.
+ */
+
+#define PCNT_CNT_H_LIM_U4  0x0000FFFF
+#define PCNT_CNT_H_LIM_U4_M  ((PCNT_CNT_H_LIM_U4_V)<<(PCNT_CNT_H_LIM_U4_S))
+#define PCNT_CNT_H_LIM_U4_V  0xFFFF
+#define PCNT_CNT_H_LIM_U4_S  0
+
+#define PCNT_U5_CONF0_REG          (DR_REG_PCNT_BASE + 0x003c)
+
+/* PCNT_CH1_LCTRL_MODE_U5 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U5_M  ((PCNT_CH1_LCTRL_MODE_U5_V)<<(PCNT_CH1_LCTRL_MODE_U5_S))
+#define PCNT_CH1_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U5_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U5 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U5_M  ((PCNT_CH1_HCTRL_MODE_U5_V)<<(PCNT_CH1_HCTRL_MODE_U5_S))
+#define PCNT_CH1_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U5_S  28
+
+/* PCNT_CH1_POS_MODE_U5 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U5  0x00000003
+#define PCNT_CH1_POS_MODE_U5_M  ((PCNT_CH1_POS_MODE_U5_V)<<(PCNT_CH1_POS_MODE_U5_S))
+#define PCNT_CH1_POS_MODE_U5_V  0x3
+#define PCNT_CH1_POS_MODE_U5_S  26
+
+/* PCNT_CH1_NEG_MODE_U5 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U5  0x00000003
+#define PCNT_CH1_NEG_MODE_U5_M  ((PCNT_CH1_NEG_MODE_U5_V)<<(PCNT_CH1_NEG_MODE_U5_S))
+#define PCNT_CH1_NEG_MODE_U5_V  0x3
+#define PCNT_CH1_NEG_MODE_U5_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U5 : R/W ;bitpos:[23:22] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U5_M  ((PCNT_CH0_LCTRL_MODE_U5_V)<<(PCNT_CH0_LCTRL_MODE_U5_S))
+#define PCNT_CH0_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U5_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U5 : R/W ;bitpos:[21:20] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's high
+ * control signal for unit5.
+ * 0:increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U5_M  ((PCNT_CH0_HCTRL_MODE_U5_V)<<(PCNT_CH0_HCTRL_MODE_U5_S))
+#define PCNT_CH0_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U5_S  20
+
+/* PCNT_CH0_POS_MODE_U5 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U5  0x00000003
+#define PCNT_CH0_POS_MODE_U5_M  ((PCNT_CH0_POS_MODE_U5_V)<<(PCNT_CH0_POS_MODE_U5_S))
+#define PCNT_CH0_POS_MODE_U5_V  0x3
+#define PCNT_CH0_POS_MODE_U5_S  18
+
+/* PCNT_CH0_NEG_MODE_U5 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U5  0x00000003
+#define PCNT_CH0_NEG_MODE_U5_M  ((PCNT_CH0_NEG_MODE_U5_V)<<(PCNT_CH0_NEG_MODE_U5_S))
+#define PCNT_CH0_NEG_MODE_U5_V  0x3
+#define PCNT_CH0_NEG_MODE_U5_S  16
+
+/* PCNT_THR_THRES1_EN_U5 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U5  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_V  0x1
+#define PCNT_THR_THRES1_EN_U5_S  15
+
+/* PCNT_THR_THRES0_EN_U5 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U5  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_V  0x1
+#define PCNT_THR_THRES0_EN_U5_S  14
+
+/* PCNT_THR_L_LIM_EN_U5 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U5  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_V  0x1
+#define PCNT_THR_L_LIM_EN_U5_S  13
+
+/* PCNT_THR_H_LIM_EN_U5 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U5  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_V  0x1
+#define PCNT_THR_H_LIM_EN_U5_S  12
+
+/* PCNT_THR_ZERO_EN_U5 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U5  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_V  0x1
+#define PCNT_THR_ZERO_EN_U5_S  11
+
+/* PCNT_FILTER_EN_U5 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit5.
+ */
+
+#define PCNT_FILTER_EN_U5  (BIT(10))
+#define PCNT_FILTER_EN_U5_M  (BIT(10))
+#define PCNT_FILTER_EN_U5_V  0x1
+#define PCNT_FILTER_EN_U5_S  10
+
+/* PCNT_FILTER_THRES_U5 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit5.
+ */
+
+#define PCNT_FILTER_THRES_U5  0x000003FF
+#define PCNT_FILTER_THRES_U5_M  ((PCNT_FILTER_THRES_U5_V)<<(PCNT_FILTER_THRES_U5_S))
+#define PCNT_FILTER_THRES_U5_V  0x3FF
+#define PCNT_FILTER_THRES_U5_S  0
+
+#define PCNT_U5_CONF1_REG          (DR_REG_PCNT_BASE + 0x0040)
+
+/* PCNT_CNT_THRES1_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit5.
+ */
+
+#define PCNT_CNT_THRES1_U5  0x0000FFFF
+#define PCNT_CNT_THRES1_U5_M  ((PCNT_CNT_THRES1_U5_V)<<(PCNT_CNT_THRES1_U5_S))
+#define PCNT_CNT_THRES1_U5_V  0xFFFF
+#define PCNT_CNT_THRES1_U5_S  16
+
+/* PCNT_CNT_THRES0_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit5.
+ */
+
+#define PCNT_CNT_THRES0_U5  0x0000FFFF
+#define PCNT_CNT_THRES0_U5_M  ((PCNT_CNT_THRES0_U5_V)<<(PCNT_CNT_THRES0_U5_S))
+#define PCNT_CNT_THRES0_U5_V  0xFFFF
+#define PCNT_CNT_THRES0_U5_S  0
+
+#define PCNT_U5_CONF2_REG          (DR_REG_PCNT_BASE + 0x0044)
+
+/* PCNT_CNT_L_LIM_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit5.
+ */
+
+#define PCNT_CNT_L_LIM_U5  0x0000FFFF
+#define PCNT_CNT_L_LIM_U5_M  ((PCNT_CNT_L_LIM_U5_V)<<(PCNT_CNT_L_LIM_U5_S))
+#define PCNT_CNT_L_LIM_U5_V  0xFFFF
+#define PCNT_CNT_L_LIM_U5_S  16
+
+/* PCNT_CNT_H_LIM_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit5.
+ */
+
+#define PCNT_CNT_H_LIM_U5  0x0000FFFF
+#define PCNT_CNT_H_LIM_U5_M  ((PCNT_CNT_H_LIM_U5_V)<<(PCNT_CNT_H_LIM_U5_S))
+#define PCNT_CNT_H_LIM_U5_V  0xFFFF
+#define PCNT_CNT_H_LIM_U5_S  0
+
+#define PCNT_U6_CONF0_REG          (DR_REG_PCNT_BASE + 0x0048)
+
+/* PCNT_CH1_LCTRL_MODE_U6 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * low control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U6_M  ((PCNT_CH1_LCTRL_MODE_U6_V)<<(PCNT_CH1_LCTRL_MODE_U6_S))
+#define PCNT_CH1_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U6_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U6 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U6_M  ((PCNT_CH1_HCTRL_MODE_U6_V)<<(PCNT_CH1_HCTRL_MODE_U6_S))
+#define PCNT_CH1_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U6_S  28
+
+/* PCNT_CH1_POS_MODE_U6 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U6  0x00000003
+#define PCNT_CH1_POS_MODE_U6_M  ((PCNT_CH1_POS_MODE_U6_V)<<(PCNT_CH1_POS_MODE_U6_S))
+#define PCNT_CH1_POS_MODE_U6_V  0x3
+#define PCNT_CH1_POS_MODE_U6_S  26
+
+/* PCNT_CH1_NEG_MODE_U6 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * input negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U6  0x00000003
+#define PCNT_CH1_NEG_MODE_U6_M  ((PCNT_CH1_NEG_MODE_U6_V)<<(PCNT_CH1_NEG_MODE_U6_S))
+#define PCNT_CH1_NEG_MODE_U6_V  0x3
+#define PCNT_CH1_NEG_MODE_U6_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U6 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U6_M  ((PCNT_CH0_LCTRL_MODE_U6_V)<<(PCNT_CH0_LCTRL_MODE_U6_S))
+#define PCNT_CH0_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U6_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U6 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * high control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U6_M  ((PCNT_CH0_HCTRL_MODE_U6_V)<<(PCNT_CH0_HCTRL_MODE_U6_S))
+#define PCNT_CH0_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U6_S  20
+
+/* PCNT_CH0_POS_MODE_U6 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U6  0x00000003
+#define PCNT_CH0_POS_MODE_U6_M  ((PCNT_CH0_POS_MODE_U6_V)<<(PCNT_CH0_POS_MODE_U6_S))
+#define PCNT_CH0_POS_MODE_U6_V  0x3
+#define PCNT_CH0_POS_MODE_U6_S  18
+
+/* PCNT_CH0_NEG_MODE_U6 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U6  0x00000003
+#define PCNT_CH0_NEG_MODE_U6_M  ((PCNT_CH0_NEG_MODE_U6_V)<<(PCNT_CH0_NEG_MODE_U6_S))
+#define PCNT_CH0_NEG_MODE_U6_V  0x3
+#define PCNT_CH0_NEG_MODE_U6_S  16
+
+/* PCNT_THR_THRES1_EN_U6 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit6's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U6  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_V  0x1
+#define PCNT_THR_THRES1_EN_U6_S  15
+
+/* PCNT_THR_THRES0_EN_U6 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U6  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_V  0x1
+#define PCNT_THR_THRES0_EN_U6_S  14
+
+/* PCNT_THR_L_LIM_EN_U6 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U6  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_V  0x1
+#define PCNT_THR_L_LIM_EN_U6_S  13
+
+/* PCNT_THR_H_LIM_EN_U6 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit6's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U6  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_V  0x1
+#define PCNT_THR_H_LIM_EN_U6_S  12
+
+/* PCNT_THR_ZERO_EN_U6 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U6  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_V  0x1
+#define PCNT_THR_ZERO_EN_U6_S  11
+
+/* PCNT_FILTER_EN_U6 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit6.
+ */
+
+#define PCNT_FILTER_EN_U6  (BIT(10))
+#define PCNT_FILTER_EN_U6_M  (BIT(10))
+#define PCNT_FILTER_EN_U6_V  0x1
+#define PCNT_FILTER_EN_U6_S  10
+
+/* PCNT_FILTER_THRES_U6 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is
+ * smaller than this value for unit6.
+ */
+
+#define PCNT_FILTER_THRES_U6  0x000003FF
+#define PCNT_FILTER_THRES_U6_M  ((PCNT_FILTER_THRES_U6_V)<<(PCNT_FILTER_THRES_U6_S))
+#define PCNT_FILTER_THRES_U6_V  0x3FF
+#define PCNT_FILTER_THRES_U6_S  0
+
+#define PCNT_U6_CONF1_REG          (DR_REG_PCNT_BASE + 0x004c)
+
+/* PCNT_CNT_THRES1_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit6.
+ */
+
+#define PCNT_CNT_THRES1_U6  0x0000FFFF
+#define PCNT_CNT_THRES1_U6_M  ((PCNT_CNT_THRES1_U6_V)<<(PCNT_CNT_THRES1_U6_S))
+#define PCNT_CNT_THRES1_U6_V  0xFFFF
+#define PCNT_CNT_THRES1_U6_S  16
+
+/* PCNT_CNT_THRES0_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit6.
+ */
+
+#define PCNT_CNT_THRES0_U6  0x0000FFFF
+#define PCNT_CNT_THRES0_U6_M  ((PCNT_CNT_THRES0_U6_V)<<(PCNT_CNT_THRES0_U6_S))
+#define PCNT_CNT_THRES0_U6_V  0xFFFF
+#define PCNT_CNT_THRES0_U6_S  0
+
+#define PCNT_U6_CONF2_REG          (DR_REG_PCNT_BASE + 0x0050)
+
+/* PCNT_CNT_L_LIM_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit6.
+ */
+
+#define PCNT_CNT_L_LIM_U6  0x0000FFFF
+#define PCNT_CNT_L_LIM_U6_M  ((PCNT_CNT_L_LIM_U6_V)<<(PCNT_CNT_L_LIM_U6_S))
+#define PCNT_CNT_L_LIM_U6_V  0xFFFF
+#define PCNT_CNT_L_LIM_U6_S  16
+
+/* PCNT_CNT_H_LIM_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit6.
+ */
+
+#define PCNT_CNT_H_LIM_U6  0x0000FFFF
+#define PCNT_CNT_H_LIM_U6_M  ((PCNT_CNT_H_LIM_U6_V)<<(PCNT_CNT_H_LIM_U6_S))
+#define PCNT_CNT_H_LIM_U6_V  0xFFFF
+#define PCNT_CNT_H_LIM_U6_S  0
+
+#define PCNT_U7_CONF0_REG          (DR_REG_PCNT_BASE + 0x0054)
+
+/* PCNT_CH1_LCTRL_MODE_U7 : R/W ;bitpos:[31:30] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U7_M  ((PCNT_CH1_LCTRL_MODE_U7_V)<<(PCNT_CH1_LCTRL_MODE_U7_S))
+#define PCNT_CH1_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U7_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U7 : R/W ;bitpos:[29:28] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U7_M  ((PCNT_CH1_HCTRL_MODE_U7_V)<<(PCNT_CH1_HCTRL_MODE_U7_S))
+#define PCNT_CH1_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U7_S  28
+
+/* PCNT_CH1_POS_MODE_U7 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2:decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U7  0x00000003
+#define PCNT_CH1_POS_MODE_U7_M  ((PCNT_CH1_POS_MODE_U7_V)<<(PCNT_CH1_POS_MODE_U7_S))
+#define PCNT_CH1_POS_MODE_U7_V  0x3
+#define PCNT_CH1_POS_MODE_U7_S  26
+
+/* PCNT_CH1_NEG_MODE_U7 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U7  0x00000003
+#define PCNT_CH1_NEG_MODE_U7_M  ((PCNT_CH1_NEG_MODE_U7_V)<<(PCNT_CH1_NEG_MODE_U7_S))
+#define PCNT_CH1_NEG_MODE_U7_V  0x3
+#define PCNT_CH1_NEG_MODE_U7_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U7 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U7_M  ((PCNT_CH0_LCTRL_MODE_U7_V)<<(PCNT_CH0_LCTRL_MODE_U7_S))
+#define PCNT_CH0_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U7_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U7 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U7_M  ((PCNT_CH0_HCTRL_MODE_U7_V)<<(PCNT_CH0_HCTRL_MODE_U7_S))
+#define PCNT_CH0_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U7_S  20
+
+/* PCNT_CH0_POS_MODE_U7 : R/W ;bitpos:[19:18] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U7  0x00000003
+#define PCNT_CH0_POS_MODE_U7_M  ((PCNT_CH0_POS_MODE_U7_V)<<(PCNT_CH0_POS_MODE_U7_S))
+#define PCNT_CH0_POS_MODE_U7_V  0x3
+#define PCNT_CH0_POS_MODE_U7_S  18
+
+/* PCNT_CH0_NEG_MODE_U7 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * input negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U7  0x00000003
+#define PCNT_CH0_NEG_MODE_U7_M  ((PCNT_CH0_NEG_MODE_U7_V)<<(PCNT_CH0_NEG_MODE_U7_S))
+#define PCNT_CH0_NEG_MODE_U7_V  0x3
+#define PCNT_CH0_NEG_MODE_U7_S  16
+
+/* PCNT_THR_THRES1_EN_U7 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit7's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U7  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_V  0x1
+#define PCNT_THR_THRES1_EN_U7_S  15
+
+/* PCNT_THR_THRES0_EN_U7 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U7  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_V  0x1
+#define PCNT_THR_THRES0_EN_U7_S  14
+
+/* PCNT_THR_L_LIM_EN_U7 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U7  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_V  0x1
+#define PCNT_THR_L_LIM_EN_U7_S  13
+
+/* PCNT_THR_H_LIM_EN_U7 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit7's count
+ * with thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U7  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_V  0x1
+#define PCNT_THR_H_LIM_EN_U7_S  12
+
+/* PCNT_THR_ZERO_EN_U7 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U7  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_V  0x1
+#define PCNT_THR_ZERO_EN_U7_S  11
+
+/* PCNT_FILTER_EN_U7 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit7.
+ */
+
+#define PCNT_FILTER_EN_U7  (BIT(10))
+#define PCNT_FILTER_EN_U7_M  (BIT(10))
+#define PCNT_FILTER_EN_U7_V  0x1
+#define PCNT_FILTER_EN_U7_S  10
+
+/* PCNT_FILTER_THRES_U7 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit7.
+ */
+
+#define PCNT_FILTER_THRES_U7  0x000003FF
+#define PCNT_FILTER_THRES_U7_M  ((PCNT_FILTER_THRES_U7_V)<<(PCNT_FILTER_THRES_U7_S))
+#define PCNT_FILTER_THRES_U7_V  0x3FF
+#define PCNT_FILTER_THRES_U7_S  0
+
+#define PCNT_U7_CONF1_REG          (DR_REG_PCNT_BASE + 0x0058)
+
+/* PCNT_CNT_THRES1_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit7.
+ */
+
+#define PCNT_CNT_THRES1_U7  0x0000FFFF
+#define PCNT_CNT_THRES1_U7_M  ((PCNT_CNT_THRES1_U7_V)<<(PCNT_CNT_THRES1_U7_S))
+#define PCNT_CNT_THRES1_U7_V  0xFFFF
+#define PCNT_CNT_THRES1_U7_S  16
+
+/* PCNT_CNT_THRES0_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit7.
+ */
+
+#define PCNT_CNT_THRES0_U7  0x0000FFFF
+#define PCNT_CNT_THRES0_U7_M  ((PCNT_CNT_THRES0_U7_V)<<(PCNT_CNT_THRES0_U7_S))
+#define PCNT_CNT_THRES0_U7_V  0xFFFF
+#define PCNT_CNT_THRES0_U7_S  0
+
+#define PCNT_U7_CONF2_REG          (DR_REG_PCNT_BASE + 0x005c)
+
+/* PCNT_CNT_L_LIM_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit7.
+ */
+
+#define PCNT_CNT_L_LIM_U7  0x0000FFFF
+#define PCNT_CNT_L_LIM_U7_M  ((PCNT_CNT_L_LIM_U7_V)<<(PCNT_CNT_L_LIM_U7_S))
+#define PCNT_CNT_L_LIM_U7_V  0xFFFF
+#define PCNT_CNT_L_LIM_U7_S  16
+
+/* PCNT_CNT_H_LIM_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit7.
+ */
+
+#define PCNT_CNT_H_LIM_U7  0x0000FFFF
+#define PCNT_CNT_H_LIM_U7_M  ((PCNT_CNT_H_LIM_U7_V)<<(PCNT_CNT_H_LIM_U7_S))
+#define PCNT_CNT_H_LIM_U7_V  0xFFFF
+#define PCNT_CNT_H_LIM_U7_S  0
+
+#define PCNT_U0_CNT_REG          (DR_REG_PCNT_BASE + 0x0060)
+
+/* PCNT_PLUS_CNT_U0 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit0.
+ */
+
+#define PCNT_PLUS_CNT_U0  0x0000FFFF
+#define PCNT_PLUS_CNT_U0_M  ((PCNT_PLUS_CNT_U0_V)<<(PCNT_PLUS_CNT_U0_S))
+#define PCNT_PLUS_CNT_U0_V  0xFFFF
+#define PCNT_PLUS_CNT_U0_S  0
+
+#define PCNT_U1_CNT_REG          (DR_REG_PCNT_BASE + 0x0064)
+
+/* PCNT_PLUS_CNT_U1 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit1.
+ */
+
+#define PCNT_PLUS_CNT_U1  0x0000FFFF
+#define PCNT_PLUS_CNT_U1_M  ((PCNT_PLUS_CNT_U1_V)<<(PCNT_PLUS_CNT_U1_S))
+#define PCNT_PLUS_CNT_U1_V  0xFFFF
+#define PCNT_PLUS_CNT_U1_S  0
+
+#define PCNT_U2_CNT_REG          (DR_REG_PCNT_BASE + 0x0068)
+
+/* PCNT_PLUS_CNT_U2 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit2.
+ */
+
+#define PCNT_PLUS_CNT_U2  0x0000FFFF
+#define PCNT_PLUS_CNT_U2_M  ((PCNT_PLUS_CNT_U2_V)<<(PCNT_PLUS_CNT_U2_S))
+#define PCNT_PLUS_CNT_U2_V  0xFFFF
+#define PCNT_PLUS_CNT_U2_S  0
+
+#define PCNT_U3_CNT_REG          (DR_REG_PCNT_BASE + 0x006c)
+
+/* PCNT_PLUS_CNT_U3 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit3.
+ */
+
+#define PCNT_PLUS_CNT_U3  0x0000FFFF
+#define PCNT_PLUS_CNT_U3_M  ((PCNT_PLUS_CNT_U3_V)<<(PCNT_PLUS_CNT_U3_S))
+#define PCNT_PLUS_CNT_U3_V  0xFFFF
+#define PCNT_PLUS_CNT_U3_S  0
+
+#define PCNT_U4_CNT_REG          (DR_REG_PCNT_BASE + 0x0070)
+
+/* PCNT_PLUS_CNT_U4 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit4.
+ */
+
+#define PCNT_PLUS_CNT_U4  0x0000FFFF
+#define PCNT_PLUS_CNT_U4_M  ((PCNT_PLUS_CNT_U4_V)<<(PCNT_PLUS_CNT_U4_S))
+#define PCNT_PLUS_CNT_U4_V  0xFFFF
+#define PCNT_PLUS_CNT_U4_S  0
+
+#define PCNT_U5_CNT_REG          (DR_REG_PCNT_BASE + 0x0074)
+
+/* PCNT_PLUS_CNT_U5 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit5.
+ */
+
+#define PCNT_PLUS_CNT_U5  0x0000FFFF
+#define PCNT_PLUS_CNT_U5_M  ((PCNT_PLUS_CNT_U5_V)<<(PCNT_PLUS_CNT_U5_S))
+#define PCNT_PLUS_CNT_U5_V  0xFFFF
+#define PCNT_PLUS_CNT_U5_S  0
+
+#define PCNT_U6_CNT_REG          (DR_REG_PCNT_BASE + 0x0078)
+
+/* PCNT_PLUS_CNT_U6 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit6.
+ */
+
+#define PCNT_PLUS_CNT_U6  0x0000FFFF
+#define PCNT_PLUS_CNT_U6_M  ((PCNT_PLUS_CNT_U6_V)<<(PCNT_PLUS_CNT_U6_S))
+#define PCNT_PLUS_CNT_U6_V  0xFFFF
+#define PCNT_PLUS_CNT_U6_S  0
+
+#define PCNT_U7_CNT_REG          (DR_REG_PCNT_BASE + 0x007c)
+
+/* PCNT_PLUS_CNT_U7 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit7.
+ */
+
+#define PCNT_PLUS_CNT_U7  0x0000FFFF
+#define PCNT_PLUS_CNT_U7_M  ((PCNT_PLUS_CNT_U7_V)<<(PCNT_PLUS_CNT_U7_S))
+#define PCNT_PLUS_CNT_U7_V  0xFFFF
+#define PCNT_PLUS_CNT_U7_S  0
+
+#define PCNT_INT_RAW_REG          (DR_REG_PCNT_BASE + 0x0080)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_RAW : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_RAW : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_RAW : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_RAW : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_RAW : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_RAW : RO ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_RAW : RO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_RAW : RO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_S  0
+
+#define PCNT_INT_ST_REG          (DR_REG_PCNT_BASE + 0x0084)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ST : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ST  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ST : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ST  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ST : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ST  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ST  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ST : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ST  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ST : RO; bitpos: [2]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U2_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ST    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_M  (PCNT_CNT_THR_EVENT_U2_INT_ST_V << PCNT_CNT_THR_EVENT_U2_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ST : RO; bitpos: [1]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U1_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ST    (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_M  (PCNT_CNT_THR_EVENT_U1_INT_ST_V << PCNT_CNT_THR_EVENT_U1_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ST : RO; bitpos: [0]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U0_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ST    (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_M  (PCNT_CNT_THR_EVENT_U0_INT_ST_V << PCNT_CNT_THR_EVENT_U0_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_S  0
+
+/* PCNT_INT_ENA_REG register
+ * Interrupt enable register
+ */
+
+#define PCNT_INT_ENA_REG          (DR_REG_PCNT_BASE + 0x0088)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ENA : R/W ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ENA : R/W ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ENA : R/W ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ENA : R/W ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ENA : R/W ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ENA : R/W ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_S  0
+
+#define PCNT_INT_CLR_REG          (DR_REG_PCNT_BASE + 0x008c)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_CLR : WO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel7 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_CLR : WO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel6 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_CLR : WO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel5 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_CLR : WO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel4 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_CLR : WO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel3 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_CLR : WO; bitpos: [2]; default: 0;
+ * Set this bit to clear the PCNT_CNT_THR_EVENT_U2_INT interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_M  (PCNT_CNT_THR_EVENT_U2_INT_CLR_V << PCNT_CNT_THR_EVENT_U2_INT_CLR_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_CLR : WO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel1 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_CLR : WO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel0 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_S  0
+
+#define PCNT_U0_STATUS_REG          (DR_REG_PCNT_BASE + 0x0090)
+
+/* PCNT_CORE_STATUS_U0 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U0  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_M  ((PCNT_CORE_STATUS_U0_V)<<(PCNT_CORE_STATUS_U0_S))
+#define PCNT_CORE_STATUS_U0_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_S  0
+
+/* 0: positive value to zero;
+ * 1: negative value to zero;
+ * 2: counter value negative;
+ * 3: counter value positive
+ */
+
+#define PCNT_STATUS_CNT_MODE    0x3
+#define PCNT_STATUS_CNT_MODE_M  ((PCNT_STATUS_CNT_MODE_V)<<(PCNT_STATUS_CNT_MODE_S))
+#define PCNT_STATUS_CNT_MODE_V  0x3
+#define PCNT_STATUS_CNT_MODE_S  0
+
+/* counter value equals to thresh1 */
+
+#define PCNT_STATUS_THRES1    BIT(2)
+#define PCNT_STATUS_THRES1_M  BIT(2)
+#define PCNT_STATUS_THRES1_V  0x1
+#define PCNT_STATUS_THRES1_S  2
+
+/* counter value equals to thresh0 */
+
+#define PCNT_STATUS_THRES0    BIT(3)
+#define PCNT_STATUS_THRES0_M  BIT(3)
+#define PCNT_STATUS_THRES0_V  0x1
+#define PCNT_STATUS_THRES0_S  3
+
+/* counter value reaches h_lim */
+
+#define PCNT_STATUS_L_LIM    BIT(4)
+#define PCNT_STATUS_L_LIM_M  BIT(4)
+#define PCNT_STATUS_L_LIM_V  0x1
+#define PCNT_STATUS_L_LIM_S  4
+
+/* counter value reaches l_lim */
+
+#define PCNT_STATUS_H_LIM    BIT(5)
+#define PCNT_STATUS_H_LIM_M  BIT(5)
+#define PCNT_STATUS_H_LIM_V  0x1
+#define PCNT_STATUS_H_LIM_S  5
+
+/* counter value equals to zero */
+
+#define PCNT_STATUS_ZERO    BIT(6)
+#define PCNT_STATUS_ZERO_M  BIT(6)
+#define PCNT_STATUS_ZERO_V  0x1
+#define PCNT_STATUS_ZERO_S  6
+
+#define PCNT_U1_STATUS_REG          (DR_REG_PCNT_BASE + 0x0094)
+
+/* PCNT_CORE_STATUS_U1 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U1  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_M  ((PCNT_CORE_STATUS_U1_V)<<(PCNT_CORE_STATUS_U1_S))
+#define PCNT_CORE_STATUS_U1_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_S  0
+
+#define PCNT_U2_STATUS_REG          (DR_REG_PCNT_BASE + 0x0098)
+
+/* PCNT_CORE_STATUS_U2 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U2  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_M  ((PCNT_CORE_STATUS_U2_V)<<(PCNT_CORE_STATUS_U2_S))
+#define PCNT_CORE_STATUS_U2_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_S  0
+
+#define PCNT_U3_STATUS_REG          (DR_REG_PCNT_BASE + 0x009c)
+
+/* PCNT_CORE_STATUS_U3 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U3  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_M  ((PCNT_CORE_STATUS_U3_V)<<(PCNT_CORE_STATUS_U3_S))
+#define PCNT_CORE_STATUS_U3_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_S  0
+
+#define PCNT_U4_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a0)
+/* PCNT_CORE_STATUS_U4 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U4  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_M  ((PCNT_CORE_STATUS_U4_V)<<(PCNT_CORE_STATUS_U4_S))
+#define PCNT_CORE_STATUS_U4_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_S  0
+
+#define PCNT_U5_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a4)
+/* PCNT_CORE_STATUS_U5 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U5  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_M  ((PCNT_CORE_STATUS_U5_V)<<(PCNT_CORE_STATUS_U5_S))
+#define PCNT_CORE_STATUS_U5_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_S  0
+
+#define PCNT_U6_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a8)
+/* PCNT_CORE_STATUS_U6 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U6  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_M  ((PCNT_CORE_STATUS_U6_V)<<(PCNT_CORE_STATUS_U6_S))
+#define PCNT_CORE_STATUS_U6_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_S  0
+
+#define PCNT_U7_STATUS_REG          (DR_REG_PCNT_BASE + 0x00ac)
+
+/* PCNT_CORE_STATUS_U7 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U7  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_M  ((PCNT_CORE_STATUS_U7_V)<<(PCNT_CORE_STATUS_U7_S))
+#define PCNT_CORE_STATUS_U7_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_S  0
+
+#define PCNT_CTRL_REG          (DR_REG_PCNT_BASE + 0x00b0)
+
+/* PCNT_CLK_EN : R/W ;bitpos:[16] ;default: 1'b0 ; */
+
+#define PCNT_CLK_EN  (BIT(16))
+#define PCNT_CLK_EN_M  (BIT(16))
+#define PCNT_CLK_EN_V  0x1
+#define PCNT_CLK_EN_S  16
+
+/* PCNT_CNT_PAUSE_U7 : R/W ;bitpos:[15] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit7's counter. */
+
+#define PCNT_CNT_PAUSE_U7  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_M  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_V  0x1
+#define PCNT_CNT_PAUSE_U7_S  15
+
+/* PCNT_PLUS_CNT_RST_U7 : R/W ;bitpos:[14] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit7's counter. */
+
+#define PCNT_PLUS_CNT_RST_U7  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_M  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_V  0x1
+#define PCNT_PLUS_CNT_RST_U7_S  14
+
+/* PCNT_CNT_PAUSE_U6 : R/W ;bitpos:[13] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit6's counter. */
+
+#define PCNT_CNT_PAUSE_U6  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_M  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_V  0x1
+#define PCNT_CNT_PAUSE_U6_S  13
+
+/* PCNT_PLUS_CNT_RST_U6 : R/W ;bitpos:[12] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit6's counter. */
+
+#define PCNT_PLUS_CNT_RST_U6  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_M  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_V  0x1
+#define PCNT_PLUS_CNT_RST_U6_S  12
+
+/* PCNT_CNT_PAUSE_U5 : R/W ;bitpos:[11] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit5's counter. */
+
+#define PCNT_CNT_PAUSE_U5  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_M  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_V  0x1
+#define PCNT_CNT_PAUSE_U5_S  11
+
+/* PCNT_PLUS_CNT_RST_U5 : R/W ;bitpos:[10] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit5's counter. */
+
+#define PCNT_PLUS_CNT_RST_U5  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_M  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_V  0x1
+#define PCNT_PLUS_CNT_RST_U5_S  10
+
+/* PCNT_CNT_PAUSE_U4 : R/W ;bitpos:[9] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit4's counter. */
+
+#define PCNT_CNT_PAUSE_U4  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_M  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_V  0x1
+#define PCNT_CNT_PAUSE_U4_S  9
+
+/* PCNT_PLUS_CNT_RST_U4 : R/W ;bitpos:[8] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit4's counter. */
+
+#define PCNT_PLUS_CNT_RST_U4  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_M  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_V  0x1
+#define PCNT_PLUS_CNT_RST_U4_S  8
+
+/* PCNT_CNT_PAUSE_U3 : R/W ;bitpos:[7] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit3's counter. */
+
+#define PCNT_CNT_PAUSE_U3  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_M  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_V  0x1
+#define PCNT_CNT_PAUSE_U3_S  7
+
+/* PCNT_PLUS_CNT_RST_U3 : R/W ;bitpos:[6] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit3's counter. */
+
+#define PCNT_PLUS_CNT_RST_U3  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_M  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_V  0x1
+#define PCNT_PLUS_CNT_RST_U3_S  6
+
+/* PCNT_CNT_PAUSE_U2 : R/W ;bitpos:[5] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit2's counter. */
+
+#define PCNT_CNT_PAUSE_U2  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_M  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_V  0x1
+#define PCNT_CNT_PAUSE_U2_S  5
+
+/* PCNT_PLUS_CNT_RST_U2 : R/W ;bitpos:[4] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit2's counter. */
+
+#define PCNT_PLUS_CNT_RST_U2  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_M  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_V  0x1
+#define PCNT_PLUS_CNT_RST_U2_S  4
+
+/* PCNT_CNT_PAUSE_U1 : R/W ;bitpos:[3] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit1's counter. */
+
+#define PCNT_CNT_PAUSE_U1  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_M  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_V  0x1
+#define PCNT_CNT_PAUSE_U1_S  3
+
+/* PCNT_PLUS_CNT_RST_U1 : R/W ;bitpos:[2] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit1's counter. */
+
+#define PCNT_PLUS_CNT_RST_U1  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_M  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_V  0x1
+#define PCNT_PLUS_CNT_RST_U1_S  2
+
+/* PCNT_CNT_PAUSE_U0 : R/W ;bitpos:[1] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit0's counter. */
+
+#define PCNT_CNT_PAUSE_U0  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_M  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_V  0x1
+#define PCNT_CNT_PAUSE_U0_S  1
+
+/* PCNT_PLUS_CNT_RST_U0 : R/W ;bitpos:[0] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit0's counter. */
+
+#define PCNT_PLUS_CNT_RST_U0  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_M  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_V  0x1
+#define PCNT_PLUS_CNT_RST_U0_S  0
+
+#define PCNT_DATE_REG          (DR_REG_PCNT_BASE + 0x00fc)
+
+/* PCNT_DATE : R/W ;bitpos:[31:0] ;default: 32'h14122600 ; */
+
+#define PCNT_DATE    0xFFFFFFFF
+#define PCNT_DATE_M  ((PCNT_DATE_V)<<(PCNT_DATE_S))

Review Comment:
   Yes, it is autogenerated by regdesc python script. But I wil fix it anyway



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] acassis commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996489348


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", pcnt);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse)
+    {
+      snerr("ERROR: PCNT%d is in-use\n", pcnt);
+      return -EBUSY;
+    }
+
+  /* Register the upper-half driver */
+
+  ret = qe_register(devpath, (struct qe_lowerhalf_s *)priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: qe_register failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Make sure that the PCNT is in the shutdown state */
+
+  esp32_shutdown((struct qe_lowerhalf_s *)priv);
+
+  /* The driver is now in-use */
+
+  priv->inuse = true;
+
+  return OK;
+}
+
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+/****************************************************************************
+ * Name: esp32_qe_index_init
+ *
+ * Description:
+ *   Register the encoder index pin to a given Qencoder timer
+ *
+ * Input Parameters:
+ *   tim  - The qenco timer number
+ *   gpio - gpio pin configuration
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qe_index_init(int tim, uint32_t gpio)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret = OK;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(tim);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", tim);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse == false)
+    {
+      snerr("ERROR: PCNT%d is not in-use\n", tim);
+      ret = -EINVAL;
+    }
+
+  /* Configure QE index pin */
+
+  priv->index_pin = gpio;
+  esp32_configgpio(priv->index_pin);
+
+  /* Register interrupt */
+
+  ret = esp32_gpiosetevent(gpio, true, false, true,
+                           esp32_qe_index_irq, priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: QE PCNT%d failed register irq\n", tim);
+      goto errout;
+    }
+
+  /* Set flag */
+
+  priv->index_use = true;

Review Comment:
   It was left from stm32 qe driver that I used as base. I will remove it



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", pcnt);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse)
+    {
+      snerr("ERROR: PCNT%d is in-use\n", pcnt);
+      return -EBUSY;
+    }
+
+  /* Register the upper-half driver */
+
+  ret = qe_register(devpath, (struct qe_lowerhalf_s *)priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: qe_register failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Make sure that the PCNT is in the shutdown state */
+
+  esp32_shutdown((struct qe_lowerhalf_s *)priv);
+
+  /* The driver is now in-use */
+
+  priv->inuse = true;
+
+  return OK;
+}
+
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+/****************************************************************************
+ * Name: esp32_qe_index_init
+ *
+ * Description:
+ *   Register the encoder index pin to a given Qencoder timer
+ *
+ * Input Parameters:
+ *   tim  - The qenco timer number
+ *   gpio - gpio pin configuration
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qe_index_init(int tim, uint32_t gpio)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret = OK;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(tim);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", tim);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse == false)
+    {
+      snerr("ERROR: PCNT%d is not in-use\n", tim);
+      ret = -EINVAL;
+    }
+
+  /* Configure QE index pin */
+
+  priv->index_pin = gpio;
+  esp32_configgpio(priv->index_pin);
+
+  /* Register interrupt */
+
+  ret = esp32_gpiosetevent(gpio, true, false, true,
+                           esp32_qe_index_irq, priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: QE PCNT%d failed register irq\n", tim);
+      goto errout;
+    }
+
+  /* Set flag */
+
+  priv->index_use = true;

Review Comment:
   It was left from stm32 qe driver that I used as base. I will remove it



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] tmedicci commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
tmedicci commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996992493


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,

Review Comment:
   Formating: `=` are not aligned



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] tmedicci commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
tmedicci commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r997005906


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)

Review Comment:
   Same here: Wouldn't it be reasonable to insert on Kconfigor somewhere else (with comment/help section?)



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);

Review Comment:
   Suggestion to improve readability:
   
   ```
     modifyreg32(PCNT_CTRL_REG, 0, PCNT_CNT_RST_U(priv->config->pcntid));
   ```



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)

Review Comment:
   Same here: Wouldn't it be reasonable to insert on Kconfigor somewhere else (with comment/help section?)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] acassis commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r997025464


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS

Review Comment:
   These configs come from original stm32_qencoder.c that I used as base!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] tmedicci commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
tmedicci commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r997004621


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS

Review Comment:
   I couldn't find any mention of this flag. Wouldn't it be reasonable to insert on `Kconfig`or somewhere else (with comment/help section?)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] tmedicci commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
tmedicci commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996993205


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */

Review Comment:
   typo: `/* FIXME: To be implemented */`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] acassis commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r997019344


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);

Review Comment:
   Good idea!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] gustavonihei commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
gustavonihei commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r997056540


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,840 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#  ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#  ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#  ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#  ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#  ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#  ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#  endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#  ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#  endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {0,1,2,3,4,5,6,7} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif

Review Comment:
   If not yet supported, it is better to simply remove this code altogether.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] acassis commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996477396


##########
arch/xtensa/src/esp32/hardware/esp32_pcnt.h:
##########
@@ -0,0 +1,2495 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/hardware/esp32_pcnt.h
+ *
+ * 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_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+#define __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* PCNT_U0_CONF0_REG register
+ * Configuration register 0 for unit 0
+ */
+
+#define PCNT_U0_CONF0_REG (DR_REG_PCNT_BASE + 0x0)
+
+/* PCNT_CH1_LCTRL_MODE_U0 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_M  (PCNT_CH1_LCTRL_MODE_U0_V << PCNT_CH1_LCTRL_MODE_U0_S)
+#define PCNT_CH1_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U0 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_M  (PCNT_CH1_HCTRL_MODE_U0_V << PCNT_CH1_HCTRL_MODE_U0_S)
+#define PCNT_CH1_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_S  28
+
+/* PCNT_CH1_POS_MODE_U0 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U0    0x00000003
+#define PCNT_CH1_POS_MODE_U0_M  (PCNT_CH1_POS_MODE_U0_V << PCNT_CH1_POS_MODE_U0_S)
+#define PCNT_CH1_POS_MODE_U0_V  0x00000003
+#define PCNT_CH1_POS_MODE_U0_S  26
+
+/* PCNT_CH1_NEG_MODE_U0 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U0    0x00000003
+#define PCNT_CH1_NEG_MODE_U0_M  (PCNT_CH1_NEG_MODE_U0_V << PCNT_CH1_NEG_MODE_U0_S)
+#define PCNT_CH1_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U0_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U0 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_M  (PCNT_CH0_LCTRL_MODE_U0_V << PCNT_CH0_LCTRL_MODE_U0_S)
+#define PCNT_CH0_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U0 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_M  (PCNT_CH0_HCTRL_MODE_U0_V << PCNT_CH0_HCTRL_MODE_U0_S)
+#define PCNT_CH0_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_S  20
+
+/* PCNT_CH0_POS_MODE_U0 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U0    0x00000003
+#define PCNT_CH0_POS_MODE_U0_M  (PCNT_CH0_POS_MODE_U0_V << PCNT_CH0_POS_MODE_U0_S)
+#define PCNT_CH0_POS_MODE_U0_V  0x00000003
+#define PCNT_CH0_POS_MODE_U0_S  18
+
+/* PCNT_CH0_NEG_MODE_U0 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U0    0x00000003
+#define PCNT_CH0_NEG_MODE_U0_M  (PCNT_CH0_NEG_MODE_U0_V << PCNT_CH0_NEG_MODE_U0_S)
+#define PCNT_CH0_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U0_S  16
+
+/* PCNT_THR_THRES1_EN_U0 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 0's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U0    (BIT(15))
+#define PCNT_THR_THRES1_EN_U0_M  (PCNT_THR_THRES1_EN_U0_V << PCNT_THR_THRES1_EN_U0_S)
+#define PCNT_THR_THRES1_EN_U0_V  0x00000001
+#define PCNT_THR_THRES1_EN_U0_S  15
+
+/* PCNT_THR_THRES0_EN_U0 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 0's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U0    (BIT(14))
+#define PCNT_THR_THRES0_EN_U0_M  (PCNT_THR_THRES0_EN_U0_V << PCNT_THR_THRES0_EN_U0_S)
+#define PCNT_THR_THRES0_EN_U0_V  0x00000001
+#define PCNT_THR_THRES0_EN_U0_S  14
+
+/* PCNT_THR_L_LIM_EN_U0 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 0's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U0    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U0_M  (PCNT_THR_L_LIM_EN_U0_V << PCNT_THR_L_LIM_EN_U0_S)
+#define PCNT_THR_L_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U0_S  13
+
+/* PCNT_THR_H_LIM_EN_U0 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 0's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U0    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U0_M  (PCNT_THR_H_LIM_EN_U0_V << PCNT_THR_H_LIM_EN_U0_S)
+#define PCNT_THR_H_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U0_S  12
+
+/* PCNT_THR_ZERO_EN_U0 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 0's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U0    (BIT(11))
+#define PCNT_THR_ZERO_EN_U0_M  (PCNT_THR_ZERO_EN_U0_V << PCNT_THR_ZERO_EN_U0_S)
+#define PCNT_THR_ZERO_EN_U0_V  0x00000001
+#define PCNT_THR_ZERO_EN_U0_S  11
+
+/* PCNT_FILTER_EN_U0 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 0's input filter.
+ */
+
+#define PCNT_FILTER_EN_U0    (BIT(10))
+#define PCNT_FILTER_EN_U0_M  (PCNT_FILTER_EN_U0_V << PCNT_FILTER_EN_U0_S)
+#define PCNT_FILTER_EN_U0_V  0x00000001
+#define PCNT_FILTER_EN_U0_S  10
+
+/* PCNT_FILTER_THRES_U0 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U0    0x000003ff
+#define PCNT_FILTER_THRES_U0_M  (PCNT_FILTER_THRES_U0_V << PCNT_FILTER_THRES_U0_S)
+#define PCNT_FILTER_THRES_U0_V  0x000003ff
+#define PCNT_FILTER_THRES_U0_S  0
+
+/* PCNT_U0_CONF1_REG register
+ * Configuration register 1 for unit 0
+ */
+
+#define PCNT_U0_CONF1_REG (DR_REG_PCNT_BASE + 0x4)
+
+/* PCNT_CNT_THRES1_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES1_U0    0x0000ffff
+#define PCNT_CNT_THRES1_U0_M  (PCNT_CNT_THRES1_U0_V << PCNT_CNT_THRES1_U0_S)
+#define PCNT_CNT_THRES1_U0_V  0x0000ffff
+#define PCNT_CNT_THRES1_U0_S  16
+
+/* PCNT_CNT_THRES0_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES0_U0    0x0000ffff
+#define PCNT_CNT_THRES0_U0_M  (PCNT_CNT_THRES0_U0_V << PCNT_CNT_THRES0_U0_S)
+#define PCNT_CNT_THRES0_U0_V  0x0000ffff
+#define PCNT_CNT_THRES0_U0_S  0
+
+/* PCNT_U0_CONF2_REG register
+ * Configuration register 2 for unit 0
+ */
+
+#define PCNT_U0_CONF2_REG (DR_REG_PCNT_BASE + 0x8)
+
+/* PCNT_CNT_L_LIM_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 0.
+ */
+
+#define PCNT_CNT_L_LIM_U0    0x0000ffff
+#define PCNT_CNT_L_LIM_U0_M  (PCNT_CNT_L_LIM_U0_V << PCNT_CNT_L_LIM_U0_S)
+#define PCNT_CNT_L_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U0_S  16
+
+/* PCNT_CNT_H_LIM_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 0.
+ */
+
+#define PCNT_CNT_H_LIM_U0    0x0000ffff
+#define PCNT_CNT_H_LIM_U0_M  (PCNT_CNT_H_LIM_U0_V << PCNT_CNT_H_LIM_U0_S)
+#define PCNT_CNT_H_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U0_S  0
+
+/* PCNT_U1_CONF0_REG register
+ * Configuration register 0 for unit 1
+ */
+
+#define PCNT_U1_CONF0_REG (DR_REG_PCNT_BASE + 0xc)
+
+/* PCNT_CH1_LCTRL_MODE_U1 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_M  (PCNT_CH1_LCTRL_MODE_U1_V << PCNT_CH1_LCTRL_MODE_U1_S)
+#define PCNT_CH1_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U1 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_M  (PCNT_CH1_HCTRL_MODE_U1_V << PCNT_CH1_HCTRL_MODE_U1_S)
+#define PCNT_CH1_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_S  28
+
+/* PCNT_CH1_POS_MODE_U1 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U1    0x00000003
+#define PCNT_CH1_POS_MODE_U1_M  (PCNT_CH1_POS_MODE_U1_V << PCNT_CH1_POS_MODE_U1_S)
+#define PCNT_CH1_POS_MODE_U1_V  0x00000003
+#define PCNT_CH1_POS_MODE_U1_S  26
+
+/* PCNT_CH1_NEG_MODE_U1 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U1    0x00000003
+#define PCNT_CH1_NEG_MODE_U1_M  (PCNT_CH1_NEG_MODE_U1_V << PCNT_CH1_NEG_MODE_U1_S)
+#define PCNT_CH1_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U1_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U1 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_M  (PCNT_CH0_LCTRL_MODE_U1_V << PCNT_CH0_LCTRL_MODE_U1_S)
+#define PCNT_CH0_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U1 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_M  (PCNT_CH0_HCTRL_MODE_U1_V << PCNT_CH0_HCTRL_MODE_U1_S)
+#define PCNT_CH0_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_S  20
+
+/* PCNT_CH0_POS_MODE_U1 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U1    0x00000003
+#define PCNT_CH0_POS_MODE_U1_M  (PCNT_CH0_POS_MODE_U1_V << PCNT_CH0_POS_MODE_U1_S)
+#define PCNT_CH0_POS_MODE_U1_V  0x00000003
+#define PCNT_CH0_POS_MODE_U1_S  18
+
+/* PCNT_CH0_NEG_MODE_U1 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U1    0x00000003
+#define PCNT_CH0_NEG_MODE_U1_M  (PCNT_CH0_NEG_MODE_U1_V << PCNT_CH0_NEG_MODE_U1_S)
+#define PCNT_CH0_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U1_S  16
+
+/* PCNT_THR_THRES1_EN_U1 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 1's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U1    (BIT(15))
+#define PCNT_THR_THRES1_EN_U1_M  (PCNT_THR_THRES1_EN_U1_V << PCNT_THR_THRES1_EN_U1_S)
+#define PCNT_THR_THRES1_EN_U1_V  0x00000001
+#define PCNT_THR_THRES1_EN_U1_S  15
+
+/* PCNT_THR_THRES0_EN_U1 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 1's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U1    (BIT(14))
+#define PCNT_THR_THRES0_EN_U1_M  (PCNT_THR_THRES0_EN_U1_V << PCNT_THR_THRES0_EN_U1_S)
+#define PCNT_THR_THRES0_EN_U1_V  0x00000001
+#define PCNT_THR_THRES0_EN_U1_S  14
+
+/* PCNT_THR_L_LIM_EN_U1 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 1's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U1    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U1_M  (PCNT_THR_L_LIM_EN_U1_V << PCNT_THR_L_LIM_EN_U1_S)
+#define PCNT_THR_L_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U1_S  13
+
+/* PCNT_THR_H_LIM_EN_U1 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 1's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U1    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U1_M  (PCNT_THR_H_LIM_EN_U1_V << PCNT_THR_H_LIM_EN_U1_S)
+#define PCNT_THR_H_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U1_S  12
+
+/* PCNT_THR_ZERO_EN_U1 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 1's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U1    (BIT(11))
+#define PCNT_THR_ZERO_EN_U1_M  (PCNT_THR_ZERO_EN_U1_V << PCNT_THR_ZERO_EN_U1_S)
+#define PCNT_THR_ZERO_EN_U1_V  0x00000001
+#define PCNT_THR_ZERO_EN_U1_S  11
+
+/* PCNT_FILTER_EN_U1 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 1's input filter.
+ */
+
+#define PCNT_FILTER_EN_U1    (BIT(10))
+#define PCNT_FILTER_EN_U1_M  (PCNT_FILTER_EN_U1_V << PCNT_FILTER_EN_U1_S)
+#define PCNT_FILTER_EN_U1_V  0x00000001
+#define PCNT_FILTER_EN_U1_S  10
+
+/* PCNT_FILTER_THRES_U1 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U1    0x000003ff
+#define PCNT_FILTER_THRES_U1_M  (PCNT_FILTER_THRES_U1_V << PCNT_FILTER_THRES_U1_S)
+#define PCNT_FILTER_THRES_U1_V  0x000003ff
+#define PCNT_FILTER_THRES_U1_S  0
+
+/* PCNT_U1_CONF1_REG register
+ * Configuration register 1 for unit 1
+ */
+
+#define PCNT_U1_CONF1_REG (DR_REG_PCNT_BASE + 0x10)
+
+/* PCNT_CNT_THRES1_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES1_U1    0x0000ffff
+#define PCNT_CNT_THRES1_U1_M  (PCNT_CNT_THRES1_U1_V << PCNT_CNT_THRES1_U1_S)
+#define PCNT_CNT_THRES1_U1_V  0x0000ffff
+#define PCNT_CNT_THRES1_U1_S  16
+
+/* PCNT_CNT_THRES0_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES0_U1    0x0000ffff
+#define PCNT_CNT_THRES0_U1_M  (PCNT_CNT_THRES0_U1_V << PCNT_CNT_THRES0_U1_S)
+#define PCNT_CNT_THRES0_U1_V  0x0000ffff
+#define PCNT_CNT_THRES0_U1_S  0
+
+/* PCNT_U1_CONF2_REG register
+ * Configuration register 2 for unit 1
+ */
+
+#define PCNT_U1_CONF2_REG (DR_REG_PCNT_BASE + 0x14)
+
+/* PCNT_CNT_L_LIM_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 1.
+ */
+
+#define PCNT_CNT_L_LIM_U1    0x0000ffff
+#define PCNT_CNT_L_LIM_U1_M  (PCNT_CNT_L_LIM_U1_V << PCNT_CNT_L_LIM_U1_S)
+#define PCNT_CNT_L_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U1_S  16
+
+/* PCNT_CNT_H_LIM_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 1.
+ */
+
+#define PCNT_CNT_H_LIM_U1    0x0000ffff
+#define PCNT_CNT_H_LIM_U1_M  (PCNT_CNT_H_LIM_U1_V << PCNT_CNT_H_LIM_U1_S)
+#define PCNT_CNT_H_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U1_S  0
+
+/* PCNT_U2_CONF0_REG register
+ * Configuration register 0 for unit 2
+ */
+
+#define PCNT_U2_CONF0_REG (DR_REG_PCNT_BASE + 0x18)
+
+/* PCNT_CH1_LCTRL_MODE_U2 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_M  (PCNT_CH1_LCTRL_MODE_U2_V << PCNT_CH1_LCTRL_MODE_U2_S)
+#define PCNT_CH1_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U2 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_M  (PCNT_CH1_HCTRL_MODE_U2_V << PCNT_CH1_HCTRL_MODE_U2_S)
+#define PCNT_CH1_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_S  28
+
+/* PCNT_CH1_POS_MODE_U2 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U2    0x00000003
+#define PCNT_CH1_POS_MODE_U2_M  (PCNT_CH1_POS_MODE_U2_V << PCNT_CH1_POS_MODE_U2_S)
+#define PCNT_CH1_POS_MODE_U2_V  0x00000003
+#define PCNT_CH1_POS_MODE_U2_S  26
+
+/* PCNT_CH1_NEG_MODE_U2 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U2    0x00000003
+#define PCNT_CH1_NEG_MODE_U2_M  (PCNT_CH1_NEG_MODE_U2_V << PCNT_CH1_NEG_MODE_U2_S)
+#define PCNT_CH1_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U2_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U2 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_M  (PCNT_CH0_LCTRL_MODE_U2_V << PCNT_CH0_LCTRL_MODE_U2_S)
+#define PCNT_CH0_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U2 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_M  (PCNT_CH0_HCTRL_MODE_U2_V << PCNT_CH0_HCTRL_MODE_U2_S)
+#define PCNT_CH0_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_S  20
+
+/* PCNT_CH0_POS_MODE_U2 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U2    0x00000003
+#define PCNT_CH0_POS_MODE_U2_M  (PCNT_CH0_POS_MODE_U2_V << PCNT_CH0_POS_MODE_U2_S)
+#define PCNT_CH0_POS_MODE_U2_V  0x00000003
+#define PCNT_CH0_POS_MODE_U2_S  18
+
+/* PCNT_CH0_NEG_MODE_U2 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U2    0x00000003
+#define PCNT_CH0_NEG_MODE_U2_M  (PCNT_CH0_NEG_MODE_U2_V << PCNT_CH0_NEG_MODE_U2_S)
+#define PCNT_CH0_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U2_S  16
+
+/* PCNT_THR_THRES1_EN_U2 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 2's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U2    (BIT(15))
+#define PCNT_THR_THRES1_EN_U2_M  (PCNT_THR_THRES1_EN_U2_V << PCNT_THR_THRES1_EN_U2_S)
+#define PCNT_THR_THRES1_EN_U2_V  0x00000001
+#define PCNT_THR_THRES1_EN_U2_S  15
+
+/* PCNT_THR_THRES0_EN_U2 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 2's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U2    (BIT(14))
+#define PCNT_THR_THRES0_EN_U2_M  (PCNT_THR_THRES0_EN_U2_V << PCNT_THR_THRES0_EN_U2_S)
+#define PCNT_THR_THRES0_EN_U2_V  0x00000001
+#define PCNT_THR_THRES0_EN_U2_S  14
+
+/* PCNT_THR_L_LIM_EN_U2 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 2's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U2    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U2_M  (PCNT_THR_L_LIM_EN_U2_V << PCNT_THR_L_LIM_EN_U2_S)
+#define PCNT_THR_L_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U2_S  13
+
+/* PCNT_THR_H_LIM_EN_U2 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 2's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U2    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U2_M  (PCNT_THR_H_LIM_EN_U2_V << PCNT_THR_H_LIM_EN_U2_S)
+#define PCNT_THR_H_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U2_S  12
+
+/* PCNT_THR_ZERO_EN_U2 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 2's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U2    (BIT(11))
+#define PCNT_THR_ZERO_EN_U2_M  (PCNT_THR_ZERO_EN_U2_V << PCNT_THR_ZERO_EN_U2_S)
+#define PCNT_THR_ZERO_EN_U2_V  0x00000001
+#define PCNT_THR_ZERO_EN_U2_S  11
+
+/* PCNT_FILTER_EN_U2 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 2's input filter.
+ */
+
+#define PCNT_FILTER_EN_U2    (BIT(10))
+#define PCNT_FILTER_EN_U2_M  (PCNT_FILTER_EN_U2_V << PCNT_FILTER_EN_U2_S)
+#define PCNT_FILTER_EN_U2_V  0x00000001
+#define PCNT_FILTER_EN_U2_S  10
+
+/* PCNT_FILTER_THRES_U2 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U2    0x000003ff
+#define PCNT_FILTER_THRES_U2_M  (PCNT_FILTER_THRES_U2_V << PCNT_FILTER_THRES_U2_S)
+#define PCNT_FILTER_THRES_U2_V  0x000003ff
+#define PCNT_FILTER_THRES_U2_S  0
+
+/* PCNT_U2_CONF1_REG register
+ * Configuration register 1 for unit 2
+ */
+
+#define PCNT_U2_CONF1_REG (DR_REG_PCNT_BASE + 0x1c)
+
+/* PCNT_CNT_THRES1_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES1_U2    0x0000ffff
+#define PCNT_CNT_THRES1_U2_M  (PCNT_CNT_THRES1_U2_V << PCNT_CNT_THRES1_U2_S)
+#define PCNT_CNT_THRES1_U2_V  0x0000ffff
+#define PCNT_CNT_THRES1_U2_S  16
+
+/* PCNT_CNT_THRES0_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES0_U2    0x0000ffff
+#define PCNT_CNT_THRES0_U2_M  (PCNT_CNT_THRES0_U2_V << PCNT_CNT_THRES0_U2_S)
+#define PCNT_CNT_THRES0_U2_V  0x0000ffff
+#define PCNT_CNT_THRES0_U2_S  0
+
+/* PCNT_U2_CONF2_REG register
+ * Configuration register 2 for unit 2
+ */
+
+#define PCNT_U2_CONF2_REG (DR_REG_PCNT_BASE + 0x20)
+
+/* PCNT_CNT_L_LIM_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 2.
+ */
+
+#define PCNT_CNT_L_LIM_U2    0x0000ffff
+#define PCNT_CNT_L_LIM_U2_M  (PCNT_CNT_L_LIM_U2_V << PCNT_CNT_L_LIM_U2_S)
+#define PCNT_CNT_L_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U2_S  16
+
+/* PCNT_CNT_H_LIM_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 2.
+ */
+
+#define PCNT_CNT_H_LIM_U2    0x0000ffff
+#define PCNT_CNT_H_LIM_U2_M  (PCNT_CNT_H_LIM_U2_V << PCNT_CNT_H_LIM_U2_S)
+#define PCNT_CNT_H_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U2_S  0
+
+/* PCNT_U3_CONF0_REG register
+ * Configuration register 0 for unit 3
+ */
+
+#define PCNT_U3_CONF0_REG (DR_REG_PCNT_BASE + 0x24)
+
+/* PCNT_CH1_LCTRL_MODE_U3 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_M  (PCNT_CH1_LCTRL_MODE_U3_V << PCNT_CH1_LCTRL_MODE_U3_S)
+#define PCNT_CH1_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U3 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_M  (PCNT_CH1_HCTRL_MODE_U3_V << PCNT_CH1_HCTRL_MODE_U3_S)
+#define PCNT_CH1_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_S  28
+
+/* PCNT_CH1_POS_MODE_U3 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U3    0x00000003
+#define PCNT_CH1_POS_MODE_U3_M  (PCNT_CH1_POS_MODE_U3_V << PCNT_CH1_POS_MODE_U3_S)
+#define PCNT_CH1_POS_MODE_U3_V  0x00000003
+#define PCNT_CH1_POS_MODE_U3_S  26
+
+/* PCNT_CH1_NEG_MODE_U3 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U3    0x00000003
+#define PCNT_CH1_NEG_MODE_U3_M  (PCNT_CH1_NEG_MODE_U3_V << PCNT_CH1_NEG_MODE_U3_S)
+#define PCNT_CH1_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U3_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U3 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_M  (PCNT_CH0_LCTRL_MODE_U3_V << PCNT_CH0_LCTRL_MODE_U3_S)
+#define PCNT_CH0_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U3 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_M  (PCNT_CH0_HCTRL_MODE_U3_V << PCNT_CH0_HCTRL_MODE_U3_S)
+#define PCNT_CH0_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_S  20
+
+/* PCNT_CH0_POS_MODE_U3 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U3    0x00000003
+#define PCNT_CH0_POS_MODE_U3_M  (PCNT_CH0_POS_MODE_U3_V << PCNT_CH0_POS_MODE_U3_S)
+#define PCNT_CH0_POS_MODE_U3_V  0x00000003
+#define PCNT_CH0_POS_MODE_U3_S  18
+
+/* PCNT_CH0_NEG_MODE_U3 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U3    0x00000003
+#define PCNT_CH0_NEG_MODE_U3_M  (PCNT_CH0_NEG_MODE_U3_V << PCNT_CH0_NEG_MODE_U3_S)
+#define PCNT_CH0_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U3_S  16
+
+/* PCNT_THR_THRES1_EN_U3 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 3's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U3    (BIT(15))
+#define PCNT_THR_THRES1_EN_U3_M  (PCNT_THR_THRES1_EN_U3_V << PCNT_THR_THRES1_EN_U3_S)
+#define PCNT_THR_THRES1_EN_U3_V  0x00000001
+#define PCNT_THR_THRES1_EN_U3_S  15
+
+/* PCNT_THR_THRES0_EN_U3 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 3's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U3    (BIT(14))
+#define PCNT_THR_THRES0_EN_U3_M  (PCNT_THR_THRES0_EN_U3_V << PCNT_THR_THRES0_EN_U3_S)
+#define PCNT_THR_THRES0_EN_U3_V  0x00000001
+#define PCNT_THR_THRES0_EN_U3_S  14
+
+/* PCNT_THR_L_LIM_EN_U3 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 3's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U3    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U3_M  (PCNT_THR_L_LIM_EN_U3_V << PCNT_THR_L_LIM_EN_U3_S)
+#define PCNT_THR_L_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U3_S  13
+
+/* PCNT_THR_H_LIM_EN_U3 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 3's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U3    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U3_M  (PCNT_THR_H_LIM_EN_U3_V << PCNT_THR_H_LIM_EN_U3_S)
+#define PCNT_THR_H_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U3_S  12
+
+/* PCNT_THR_ZERO_EN_U3 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 3's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U3    (BIT(11))
+#define PCNT_THR_ZERO_EN_U3_M  (PCNT_THR_ZERO_EN_U3_V << PCNT_THR_ZERO_EN_U3_S)
+#define PCNT_THR_ZERO_EN_U3_V  0x00000001
+#define PCNT_THR_ZERO_EN_U3_S  11
+
+/* PCNT_FILTER_EN_U3 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 3's input filter.
+ */
+
+#define PCNT_FILTER_EN_U3    (BIT(10))
+#define PCNT_FILTER_EN_U3_M  (PCNT_FILTER_EN_U3_V << PCNT_FILTER_EN_U3_S)
+#define PCNT_FILTER_EN_U3_V  0x00000001
+#define PCNT_FILTER_EN_U3_S  10
+
+/* PCNT_FILTER_THRES_U3 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U3    0x000003ff
+#define PCNT_FILTER_THRES_U3_M  (PCNT_FILTER_THRES_U3_V << PCNT_FILTER_THRES_U3_S)
+#define PCNT_FILTER_THRES_U3_V  0x000003ff
+#define PCNT_FILTER_THRES_U3_S  0
+
+/* PCNT_U3_CONF1_REG register
+ * Configuration register 1 for unit 3
+ */
+
+#define PCNT_U3_CONF1_REG (DR_REG_PCNT_BASE + 0x28)
+
+/* PCNT_CNT_THRES1_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES1_U3    0x0000ffff
+#define PCNT_CNT_THRES1_U3_M  (PCNT_CNT_THRES1_U3_V << PCNT_CNT_THRES1_U3_S)
+#define PCNT_CNT_THRES1_U3_V  0x0000ffff
+#define PCNT_CNT_THRES1_U3_S  16
+
+/* PCNT_CNT_THRES0_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES0_U3    0x0000ffff
+#define PCNT_CNT_THRES0_U3_M  (PCNT_CNT_THRES0_U3_V << PCNT_CNT_THRES0_U3_S)
+#define PCNT_CNT_THRES0_U3_V  0x0000ffff
+#define PCNT_CNT_THRES0_U3_S  0
+
+/* PCNT_U3_CONF2_REG register
+ * Configuration register 2 for unit 3
+ */
+
+#define PCNT_U3_CONF2_REG (DR_REG_PCNT_BASE + 0x2c)
+
+/* PCNT_CNT_L_LIM_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 3.
+ */
+
+#define PCNT_CNT_L_LIM_U3    0x0000ffff
+#define PCNT_CNT_L_LIM_U3_M  (PCNT_CNT_L_LIM_U3_V << PCNT_CNT_L_LIM_U3_S)
+#define PCNT_CNT_L_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U3_S  16
+
+/* PCNT_CNT_H_LIM_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 3.
+ */
+
+#define PCNT_CNT_H_LIM_U3    0x0000ffff
+#define PCNT_CNT_H_LIM_U3_M  (PCNT_CNT_H_LIM_U3_V << PCNT_CNT_H_LIM_U3_S)
+#define PCNT_CNT_H_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U3_S  0
+
+#define PCNT_U4_CONF0_REG          (DR_REG_PCNT_BASE + 0x0030)
+
+/* PCNT_CH1_LCTRL_MODE_U4 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U4_M  ((PCNT_CH1_LCTRL_MODE_U4_V)<<(PCNT_CH1_LCTRL_MODE_U4_S))
+#define PCNT_CH1_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U4_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U4 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U4_M  ((PCNT_CH1_HCTRL_MODE_U4_V)<<(PCNT_CH1_HCTRL_MODE_U4_S))
+#define PCNT_CH1_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U4_S  28
+
+/* PCNT_CH1_POS_MODE_U4 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U4  0x00000003
+#define PCNT_CH1_POS_MODE_U4_M  ((PCNT_CH1_POS_MODE_U4_V)<<(PCNT_CH1_POS_MODE_U4_S))
+#define PCNT_CH1_POS_MODE_U4_V  0x3
+#define PCNT_CH1_POS_MODE_U4_S  26
+
+/* PCNT_CH1_NEG_MODE_U4 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U4  0x00000003
+#define PCNT_CH1_NEG_MODE_U4_M  ((PCNT_CH1_NEG_MODE_U4_V)<<(PCNT_CH1_NEG_MODE_U4_S))
+#define PCNT_CH1_NEG_MODE_U4_V  0x3
+#define PCNT_CH1_NEG_MODE_U4_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U4 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U4_M  ((PCNT_CH0_LCTRL_MODE_U4_V)<<(PCNT_CH0_LCTRL_MODE_U4_S))
+#define PCNT_CH0_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U4_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U4 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U4_M  ((PCNT_CH0_HCTRL_MODE_U4_V)<<(PCNT_CH0_HCTRL_MODE_U4_S))
+#define PCNT_CH0_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U4_S  20
+
+/* PCNT_CH0_POS_MODE_U4 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U4  0x00000003
+#define PCNT_CH0_POS_MODE_U4_M  ((PCNT_CH0_POS_MODE_U4_V)<<(PCNT_CH0_POS_MODE_U4_S))
+#define PCNT_CH0_POS_MODE_U4_V  0x3
+#define PCNT_CH0_POS_MODE_U4_S  18
+
+/* PCNT_CH0_NEG_MODE_U4 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U4  0x00000003
+#define PCNT_CH0_NEG_MODE_U4_M  ((PCNT_CH0_NEG_MODE_U4_V)<<(PCNT_CH0_NEG_MODE_U4_S))
+#define PCNT_CH0_NEG_MODE_U4_V  0x3
+#define PCNT_CH0_NEG_MODE_U4_S  16
+
+/* PCNT_THR_THRES1_EN_U4 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U4  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_V  0x1
+#define PCNT_THR_THRES1_EN_U4_S  15
+
+/* PCNT_THR_THRES0_EN_U4 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U4  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_V  0x1
+#define PCNT_THR_THRES0_EN_U4_S  14
+
+/* PCNT_THR_L_LIM_EN_U4 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_l_lim  value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U4  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_V  0x1
+#define PCNT_THR_L_LIM_EN_U4_S  13
+
+/* PCNT_THR_H_LIM_EN_U4 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U4  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_V  0x1
+#define PCNT_THR_H_LIM_EN_U4_S  12
+
+/* PCNT_THR_ZERO_EN_U4 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U4  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_V  0x1
+#define PCNT_THR_ZERO_EN_U4_S  11
+
+/* PCNT_FILTER_EN_U4 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit4.
+ */
+
+#define PCNT_FILTER_EN_U4  (BIT(10))
+#define PCNT_FILTER_EN_U4_M  (BIT(10))
+#define PCNT_FILTER_EN_U4_V  0x1
+#define PCNT_FILTER_EN_U4_S  10
+
+/* PCNT_FILTER_THRES_U4 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit4.
+ */
+
+#define PCNT_FILTER_THRES_U4  0x000003FF
+#define PCNT_FILTER_THRES_U4_M  ((PCNT_FILTER_THRES_U4_V)<<(PCNT_FILTER_THRES_U4_S))
+#define PCNT_FILTER_THRES_U4_V  0x3FF
+#define PCNT_FILTER_THRES_U4_S  0
+
+#define PCNT_U4_CONF1_REG          (DR_REG_PCNT_BASE + 0x0034)
+
+/* PCNT_CNT_THRES1_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure thres1 value for unit4.
+ */
+
+#define PCNT_CNT_THRES1_U4  0x0000FFFF
+#define PCNT_CNT_THRES1_U4_M  ((PCNT_CNT_THRES1_U4_V)<<(PCNT_CNT_THRES1_U4_S))
+#define PCNT_CNT_THRES1_U4_V  0xFFFF
+#define PCNT_CNT_THRES1_U4_S  16
+
+/* PCNT_CNT_THRES0_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit4.
+ */
+
+#define PCNT_CNT_THRES0_U4  0x0000FFFF
+#define PCNT_CNT_THRES0_U4_M  ((PCNT_CNT_THRES0_U4_V)<<(PCNT_CNT_THRES0_U4_S))
+#define PCNT_CNT_THRES0_U4_V  0xFFFF
+#define PCNT_CNT_THRES0_U4_S  0
+
+#define PCNT_U4_CONF2_REG          (DR_REG_PCNT_BASE + 0x0038)
+
+/* PCNT_CNT_L_LIM_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit4.
+ */
+
+#define PCNT_CNT_L_LIM_U4  0x0000FFFF
+#define PCNT_CNT_L_LIM_U4_M  ((PCNT_CNT_L_LIM_U4_V)<<(PCNT_CNT_L_LIM_U4_S))
+#define PCNT_CNT_L_LIM_U4_V  0xFFFF
+#define PCNT_CNT_L_LIM_U4_S  16
+
+/* PCNT_CNT_H_LIM_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit4.
+ */
+
+#define PCNT_CNT_H_LIM_U4  0x0000FFFF
+#define PCNT_CNT_H_LIM_U4_M  ((PCNT_CNT_H_LIM_U4_V)<<(PCNT_CNT_H_LIM_U4_S))
+#define PCNT_CNT_H_LIM_U4_V  0xFFFF
+#define PCNT_CNT_H_LIM_U4_S  0
+
+#define PCNT_U5_CONF0_REG          (DR_REG_PCNT_BASE + 0x003c)
+
+/* PCNT_CH1_LCTRL_MODE_U5 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U5_M  ((PCNT_CH1_LCTRL_MODE_U5_V)<<(PCNT_CH1_LCTRL_MODE_U5_S))
+#define PCNT_CH1_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U5_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U5 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U5_M  ((PCNT_CH1_HCTRL_MODE_U5_V)<<(PCNT_CH1_HCTRL_MODE_U5_S))
+#define PCNT_CH1_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U5_S  28
+
+/* PCNT_CH1_POS_MODE_U5 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U5  0x00000003
+#define PCNT_CH1_POS_MODE_U5_M  ((PCNT_CH1_POS_MODE_U5_V)<<(PCNT_CH1_POS_MODE_U5_S))
+#define PCNT_CH1_POS_MODE_U5_V  0x3
+#define PCNT_CH1_POS_MODE_U5_S  26
+
+/* PCNT_CH1_NEG_MODE_U5 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U5  0x00000003
+#define PCNT_CH1_NEG_MODE_U5_M  ((PCNT_CH1_NEG_MODE_U5_V)<<(PCNT_CH1_NEG_MODE_U5_S))
+#define PCNT_CH1_NEG_MODE_U5_V  0x3
+#define PCNT_CH1_NEG_MODE_U5_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U5 : R/W ;bitpos:[23:22] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U5_M  ((PCNT_CH0_LCTRL_MODE_U5_V)<<(PCNT_CH0_LCTRL_MODE_U5_S))
+#define PCNT_CH0_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U5_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U5 : R/W ;bitpos:[21:20] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's high
+ * control signal for unit5.
+ * 0:increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U5_M  ((PCNT_CH0_HCTRL_MODE_U5_V)<<(PCNT_CH0_HCTRL_MODE_U5_S))
+#define PCNT_CH0_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U5_S  20
+
+/* PCNT_CH0_POS_MODE_U5 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U5  0x00000003
+#define PCNT_CH0_POS_MODE_U5_M  ((PCNT_CH0_POS_MODE_U5_V)<<(PCNT_CH0_POS_MODE_U5_S))
+#define PCNT_CH0_POS_MODE_U5_V  0x3
+#define PCNT_CH0_POS_MODE_U5_S  18
+
+/* PCNT_CH0_NEG_MODE_U5 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U5  0x00000003
+#define PCNT_CH0_NEG_MODE_U5_M  ((PCNT_CH0_NEG_MODE_U5_V)<<(PCNT_CH0_NEG_MODE_U5_S))
+#define PCNT_CH0_NEG_MODE_U5_V  0x3
+#define PCNT_CH0_NEG_MODE_U5_S  16
+
+/* PCNT_THR_THRES1_EN_U5 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U5  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_V  0x1
+#define PCNT_THR_THRES1_EN_U5_S  15
+
+/* PCNT_THR_THRES0_EN_U5 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U5  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_V  0x1
+#define PCNT_THR_THRES0_EN_U5_S  14
+
+/* PCNT_THR_L_LIM_EN_U5 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U5  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_V  0x1
+#define PCNT_THR_L_LIM_EN_U5_S  13
+
+/* PCNT_THR_H_LIM_EN_U5 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U5  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_V  0x1
+#define PCNT_THR_H_LIM_EN_U5_S  12
+
+/* PCNT_THR_ZERO_EN_U5 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U5  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_V  0x1
+#define PCNT_THR_ZERO_EN_U5_S  11
+
+/* PCNT_FILTER_EN_U5 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit5.
+ */
+
+#define PCNT_FILTER_EN_U5  (BIT(10))
+#define PCNT_FILTER_EN_U5_M  (BIT(10))
+#define PCNT_FILTER_EN_U5_V  0x1
+#define PCNT_FILTER_EN_U5_S  10
+
+/* PCNT_FILTER_THRES_U5 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit5.
+ */
+
+#define PCNT_FILTER_THRES_U5  0x000003FF
+#define PCNT_FILTER_THRES_U5_M  ((PCNT_FILTER_THRES_U5_V)<<(PCNT_FILTER_THRES_U5_S))
+#define PCNT_FILTER_THRES_U5_V  0x3FF
+#define PCNT_FILTER_THRES_U5_S  0
+
+#define PCNT_U5_CONF1_REG          (DR_REG_PCNT_BASE + 0x0040)
+
+/* PCNT_CNT_THRES1_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit5.
+ */
+
+#define PCNT_CNT_THRES1_U5  0x0000FFFF
+#define PCNT_CNT_THRES1_U5_M  ((PCNT_CNT_THRES1_U5_V)<<(PCNT_CNT_THRES1_U5_S))
+#define PCNT_CNT_THRES1_U5_V  0xFFFF
+#define PCNT_CNT_THRES1_U5_S  16
+
+/* PCNT_CNT_THRES0_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit5.
+ */
+
+#define PCNT_CNT_THRES0_U5  0x0000FFFF
+#define PCNT_CNT_THRES0_U5_M  ((PCNT_CNT_THRES0_U5_V)<<(PCNT_CNT_THRES0_U5_S))
+#define PCNT_CNT_THRES0_U5_V  0xFFFF
+#define PCNT_CNT_THRES0_U5_S  0
+
+#define PCNT_U5_CONF2_REG          (DR_REG_PCNT_BASE + 0x0044)
+
+/* PCNT_CNT_L_LIM_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit5.
+ */
+
+#define PCNT_CNT_L_LIM_U5  0x0000FFFF
+#define PCNT_CNT_L_LIM_U5_M  ((PCNT_CNT_L_LIM_U5_V)<<(PCNT_CNT_L_LIM_U5_S))
+#define PCNT_CNT_L_LIM_U5_V  0xFFFF
+#define PCNT_CNT_L_LIM_U5_S  16
+
+/* PCNT_CNT_H_LIM_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit5.
+ */
+
+#define PCNT_CNT_H_LIM_U5  0x0000FFFF
+#define PCNT_CNT_H_LIM_U5_M  ((PCNT_CNT_H_LIM_U5_V)<<(PCNT_CNT_H_LIM_U5_S))
+#define PCNT_CNT_H_LIM_U5_V  0xFFFF
+#define PCNT_CNT_H_LIM_U5_S  0
+
+#define PCNT_U6_CONF0_REG          (DR_REG_PCNT_BASE + 0x0048)
+
+/* PCNT_CH1_LCTRL_MODE_U6 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * low control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U6_M  ((PCNT_CH1_LCTRL_MODE_U6_V)<<(PCNT_CH1_LCTRL_MODE_U6_S))
+#define PCNT_CH1_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U6_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U6 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U6_M  ((PCNT_CH1_HCTRL_MODE_U6_V)<<(PCNT_CH1_HCTRL_MODE_U6_S))
+#define PCNT_CH1_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U6_S  28
+
+/* PCNT_CH1_POS_MODE_U6 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U6  0x00000003
+#define PCNT_CH1_POS_MODE_U6_M  ((PCNT_CH1_POS_MODE_U6_V)<<(PCNT_CH1_POS_MODE_U6_S))
+#define PCNT_CH1_POS_MODE_U6_V  0x3
+#define PCNT_CH1_POS_MODE_U6_S  26
+
+/* PCNT_CH1_NEG_MODE_U6 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * input negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U6  0x00000003
+#define PCNT_CH1_NEG_MODE_U6_M  ((PCNT_CH1_NEG_MODE_U6_V)<<(PCNT_CH1_NEG_MODE_U6_S))
+#define PCNT_CH1_NEG_MODE_U6_V  0x3
+#define PCNT_CH1_NEG_MODE_U6_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U6 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U6_M  ((PCNT_CH0_LCTRL_MODE_U6_V)<<(PCNT_CH0_LCTRL_MODE_U6_S))
+#define PCNT_CH0_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U6_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U6 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * high control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U6_M  ((PCNT_CH0_HCTRL_MODE_U6_V)<<(PCNT_CH0_HCTRL_MODE_U6_S))
+#define PCNT_CH0_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U6_S  20
+
+/* PCNT_CH0_POS_MODE_U6 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U6  0x00000003
+#define PCNT_CH0_POS_MODE_U6_M  ((PCNT_CH0_POS_MODE_U6_V)<<(PCNT_CH0_POS_MODE_U6_S))
+#define PCNT_CH0_POS_MODE_U6_V  0x3
+#define PCNT_CH0_POS_MODE_U6_S  18
+
+/* PCNT_CH0_NEG_MODE_U6 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U6  0x00000003
+#define PCNT_CH0_NEG_MODE_U6_M  ((PCNT_CH0_NEG_MODE_U6_V)<<(PCNT_CH0_NEG_MODE_U6_S))
+#define PCNT_CH0_NEG_MODE_U6_V  0x3
+#define PCNT_CH0_NEG_MODE_U6_S  16
+
+/* PCNT_THR_THRES1_EN_U6 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit6's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U6  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_V  0x1
+#define PCNT_THR_THRES1_EN_U6_S  15
+
+/* PCNT_THR_THRES0_EN_U6 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U6  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_V  0x1
+#define PCNT_THR_THRES0_EN_U6_S  14
+
+/* PCNT_THR_L_LIM_EN_U6 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U6  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_V  0x1
+#define PCNT_THR_L_LIM_EN_U6_S  13
+
+/* PCNT_THR_H_LIM_EN_U6 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit6's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U6  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_V  0x1
+#define PCNT_THR_H_LIM_EN_U6_S  12
+
+/* PCNT_THR_ZERO_EN_U6 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U6  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_V  0x1
+#define PCNT_THR_ZERO_EN_U6_S  11
+
+/* PCNT_FILTER_EN_U6 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit6.
+ */
+
+#define PCNT_FILTER_EN_U6  (BIT(10))
+#define PCNT_FILTER_EN_U6_M  (BIT(10))
+#define PCNT_FILTER_EN_U6_V  0x1
+#define PCNT_FILTER_EN_U6_S  10
+
+/* PCNT_FILTER_THRES_U6 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is
+ * smaller than this value for unit6.
+ */
+
+#define PCNT_FILTER_THRES_U6  0x000003FF
+#define PCNT_FILTER_THRES_U6_M  ((PCNT_FILTER_THRES_U6_V)<<(PCNT_FILTER_THRES_U6_S))
+#define PCNT_FILTER_THRES_U6_V  0x3FF
+#define PCNT_FILTER_THRES_U6_S  0
+
+#define PCNT_U6_CONF1_REG          (DR_REG_PCNT_BASE + 0x004c)
+
+/* PCNT_CNT_THRES1_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit6.
+ */
+
+#define PCNT_CNT_THRES1_U6  0x0000FFFF
+#define PCNT_CNT_THRES1_U6_M  ((PCNT_CNT_THRES1_U6_V)<<(PCNT_CNT_THRES1_U6_S))
+#define PCNT_CNT_THRES1_U6_V  0xFFFF
+#define PCNT_CNT_THRES1_U6_S  16
+
+/* PCNT_CNT_THRES0_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit6.
+ */
+
+#define PCNT_CNT_THRES0_U6  0x0000FFFF
+#define PCNT_CNT_THRES0_U6_M  ((PCNT_CNT_THRES0_U6_V)<<(PCNT_CNT_THRES0_U6_S))
+#define PCNT_CNT_THRES0_U6_V  0xFFFF
+#define PCNT_CNT_THRES0_U6_S  0
+
+#define PCNT_U6_CONF2_REG          (DR_REG_PCNT_BASE + 0x0050)
+
+/* PCNT_CNT_L_LIM_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit6.
+ */
+
+#define PCNT_CNT_L_LIM_U6  0x0000FFFF
+#define PCNT_CNT_L_LIM_U6_M  ((PCNT_CNT_L_LIM_U6_V)<<(PCNT_CNT_L_LIM_U6_S))
+#define PCNT_CNT_L_LIM_U6_V  0xFFFF
+#define PCNT_CNT_L_LIM_U6_S  16
+
+/* PCNT_CNT_H_LIM_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit6.
+ */
+
+#define PCNT_CNT_H_LIM_U6  0x0000FFFF
+#define PCNT_CNT_H_LIM_U6_M  ((PCNT_CNT_H_LIM_U6_V)<<(PCNT_CNT_H_LIM_U6_S))
+#define PCNT_CNT_H_LIM_U6_V  0xFFFF
+#define PCNT_CNT_H_LIM_U6_S  0
+
+#define PCNT_U7_CONF0_REG          (DR_REG_PCNT_BASE + 0x0054)
+
+/* PCNT_CH1_LCTRL_MODE_U7 : R/W ;bitpos:[31:30] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U7_M  ((PCNT_CH1_LCTRL_MODE_U7_V)<<(PCNT_CH1_LCTRL_MODE_U7_S))
+#define PCNT_CH1_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U7_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U7 : R/W ;bitpos:[29:28] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U7_M  ((PCNT_CH1_HCTRL_MODE_U7_V)<<(PCNT_CH1_HCTRL_MODE_U7_S))
+#define PCNT_CH1_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U7_S  28
+
+/* PCNT_CH1_POS_MODE_U7 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2:decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U7  0x00000003
+#define PCNT_CH1_POS_MODE_U7_M  ((PCNT_CH1_POS_MODE_U7_V)<<(PCNT_CH1_POS_MODE_U7_S))
+#define PCNT_CH1_POS_MODE_U7_V  0x3
+#define PCNT_CH1_POS_MODE_U7_S  26
+
+/* PCNT_CH1_NEG_MODE_U7 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U7  0x00000003
+#define PCNT_CH1_NEG_MODE_U7_M  ((PCNT_CH1_NEG_MODE_U7_V)<<(PCNT_CH1_NEG_MODE_U7_S))
+#define PCNT_CH1_NEG_MODE_U7_V  0x3
+#define PCNT_CH1_NEG_MODE_U7_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U7 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U7_M  ((PCNT_CH0_LCTRL_MODE_U7_V)<<(PCNT_CH0_LCTRL_MODE_U7_S))
+#define PCNT_CH0_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U7_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U7 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U7_M  ((PCNT_CH0_HCTRL_MODE_U7_V)<<(PCNT_CH0_HCTRL_MODE_U7_S))
+#define PCNT_CH0_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U7_S  20
+
+/* PCNT_CH0_POS_MODE_U7 : R/W ;bitpos:[19:18] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U7  0x00000003
+#define PCNT_CH0_POS_MODE_U7_M  ((PCNT_CH0_POS_MODE_U7_V)<<(PCNT_CH0_POS_MODE_U7_S))
+#define PCNT_CH0_POS_MODE_U7_V  0x3
+#define PCNT_CH0_POS_MODE_U7_S  18
+
+/* PCNT_CH0_NEG_MODE_U7 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * input negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U7  0x00000003
+#define PCNT_CH0_NEG_MODE_U7_M  ((PCNT_CH0_NEG_MODE_U7_V)<<(PCNT_CH0_NEG_MODE_U7_S))
+#define PCNT_CH0_NEG_MODE_U7_V  0x3
+#define PCNT_CH0_NEG_MODE_U7_S  16
+
+/* PCNT_THR_THRES1_EN_U7 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit7's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U7  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_V  0x1
+#define PCNT_THR_THRES1_EN_U7_S  15
+
+/* PCNT_THR_THRES0_EN_U7 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U7  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_V  0x1
+#define PCNT_THR_THRES0_EN_U7_S  14
+
+/* PCNT_THR_L_LIM_EN_U7 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U7  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_V  0x1
+#define PCNT_THR_L_LIM_EN_U7_S  13
+
+/* PCNT_THR_H_LIM_EN_U7 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit7's count
+ * with thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U7  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_V  0x1
+#define PCNT_THR_H_LIM_EN_U7_S  12
+
+/* PCNT_THR_ZERO_EN_U7 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U7  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_V  0x1
+#define PCNT_THR_ZERO_EN_U7_S  11
+
+/* PCNT_FILTER_EN_U7 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit7.
+ */
+
+#define PCNT_FILTER_EN_U7  (BIT(10))
+#define PCNT_FILTER_EN_U7_M  (BIT(10))
+#define PCNT_FILTER_EN_U7_V  0x1
+#define PCNT_FILTER_EN_U7_S  10
+
+/* PCNT_FILTER_THRES_U7 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit7.
+ */
+
+#define PCNT_FILTER_THRES_U7  0x000003FF
+#define PCNT_FILTER_THRES_U7_M  ((PCNT_FILTER_THRES_U7_V)<<(PCNT_FILTER_THRES_U7_S))
+#define PCNT_FILTER_THRES_U7_V  0x3FF
+#define PCNT_FILTER_THRES_U7_S  0
+
+#define PCNT_U7_CONF1_REG          (DR_REG_PCNT_BASE + 0x0058)
+
+/* PCNT_CNT_THRES1_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit7.
+ */
+
+#define PCNT_CNT_THRES1_U7  0x0000FFFF
+#define PCNT_CNT_THRES1_U7_M  ((PCNT_CNT_THRES1_U7_V)<<(PCNT_CNT_THRES1_U7_S))
+#define PCNT_CNT_THRES1_U7_V  0xFFFF
+#define PCNT_CNT_THRES1_U7_S  16
+
+/* PCNT_CNT_THRES0_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit7.
+ */
+
+#define PCNT_CNT_THRES0_U7  0x0000FFFF
+#define PCNT_CNT_THRES0_U7_M  ((PCNT_CNT_THRES0_U7_V)<<(PCNT_CNT_THRES0_U7_S))
+#define PCNT_CNT_THRES0_U7_V  0xFFFF
+#define PCNT_CNT_THRES0_U7_S  0
+
+#define PCNT_U7_CONF2_REG          (DR_REG_PCNT_BASE + 0x005c)
+
+/* PCNT_CNT_L_LIM_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit7.
+ */
+
+#define PCNT_CNT_L_LIM_U7  0x0000FFFF
+#define PCNT_CNT_L_LIM_U7_M  ((PCNT_CNT_L_LIM_U7_V)<<(PCNT_CNT_L_LIM_U7_S))
+#define PCNT_CNT_L_LIM_U7_V  0xFFFF
+#define PCNT_CNT_L_LIM_U7_S  16
+
+/* PCNT_CNT_H_LIM_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit7.
+ */
+
+#define PCNT_CNT_H_LIM_U7  0x0000FFFF
+#define PCNT_CNT_H_LIM_U7_M  ((PCNT_CNT_H_LIM_U7_V)<<(PCNT_CNT_H_LIM_U7_S))
+#define PCNT_CNT_H_LIM_U7_V  0xFFFF
+#define PCNT_CNT_H_LIM_U7_S  0
+
+#define PCNT_U0_CNT_REG          (DR_REG_PCNT_BASE + 0x0060)
+
+/* PCNT_PLUS_CNT_U0 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit0.
+ */
+
+#define PCNT_PLUS_CNT_U0  0x0000FFFF
+#define PCNT_PLUS_CNT_U0_M  ((PCNT_PLUS_CNT_U0_V)<<(PCNT_PLUS_CNT_U0_S))
+#define PCNT_PLUS_CNT_U0_V  0xFFFF
+#define PCNT_PLUS_CNT_U0_S  0
+
+#define PCNT_U1_CNT_REG          (DR_REG_PCNT_BASE + 0x0064)
+
+/* PCNT_PLUS_CNT_U1 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit1.
+ */
+
+#define PCNT_PLUS_CNT_U1  0x0000FFFF
+#define PCNT_PLUS_CNT_U1_M  ((PCNT_PLUS_CNT_U1_V)<<(PCNT_PLUS_CNT_U1_S))
+#define PCNT_PLUS_CNT_U1_V  0xFFFF
+#define PCNT_PLUS_CNT_U1_S  0
+
+#define PCNT_U2_CNT_REG          (DR_REG_PCNT_BASE + 0x0068)
+
+/* PCNT_PLUS_CNT_U2 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit2.
+ */
+
+#define PCNT_PLUS_CNT_U2  0x0000FFFF
+#define PCNT_PLUS_CNT_U2_M  ((PCNT_PLUS_CNT_U2_V)<<(PCNT_PLUS_CNT_U2_S))
+#define PCNT_PLUS_CNT_U2_V  0xFFFF
+#define PCNT_PLUS_CNT_U2_S  0
+
+#define PCNT_U3_CNT_REG          (DR_REG_PCNT_BASE + 0x006c)
+
+/* PCNT_PLUS_CNT_U3 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit3.
+ */
+
+#define PCNT_PLUS_CNT_U3  0x0000FFFF
+#define PCNT_PLUS_CNT_U3_M  ((PCNT_PLUS_CNT_U3_V)<<(PCNT_PLUS_CNT_U3_S))
+#define PCNT_PLUS_CNT_U3_V  0xFFFF
+#define PCNT_PLUS_CNT_U3_S  0
+
+#define PCNT_U4_CNT_REG          (DR_REG_PCNT_BASE + 0x0070)
+
+/* PCNT_PLUS_CNT_U4 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit4.
+ */
+
+#define PCNT_PLUS_CNT_U4  0x0000FFFF
+#define PCNT_PLUS_CNT_U4_M  ((PCNT_PLUS_CNT_U4_V)<<(PCNT_PLUS_CNT_U4_S))
+#define PCNT_PLUS_CNT_U4_V  0xFFFF
+#define PCNT_PLUS_CNT_U4_S  0
+
+#define PCNT_U5_CNT_REG          (DR_REG_PCNT_BASE + 0x0074)
+
+/* PCNT_PLUS_CNT_U5 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit5.
+ */
+
+#define PCNT_PLUS_CNT_U5  0x0000FFFF
+#define PCNT_PLUS_CNT_U5_M  ((PCNT_PLUS_CNT_U5_V)<<(PCNT_PLUS_CNT_U5_S))
+#define PCNT_PLUS_CNT_U5_V  0xFFFF
+#define PCNT_PLUS_CNT_U5_S  0
+
+#define PCNT_U6_CNT_REG          (DR_REG_PCNT_BASE + 0x0078)
+
+/* PCNT_PLUS_CNT_U6 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit6.
+ */
+
+#define PCNT_PLUS_CNT_U6  0x0000FFFF
+#define PCNT_PLUS_CNT_U6_M  ((PCNT_PLUS_CNT_U6_V)<<(PCNT_PLUS_CNT_U6_S))
+#define PCNT_PLUS_CNT_U6_V  0xFFFF
+#define PCNT_PLUS_CNT_U6_S  0
+
+#define PCNT_U7_CNT_REG          (DR_REG_PCNT_BASE + 0x007c)
+
+/* PCNT_PLUS_CNT_U7 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit7.
+ */
+
+#define PCNT_PLUS_CNT_U7  0x0000FFFF
+#define PCNT_PLUS_CNT_U7_M  ((PCNT_PLUS_CNT_U7_V)<<(PCNT_PLUS_CNT_U7_S))
+#define PCNT_PLUS_CNT_U7_V  0xFFFF
+#define PCNT_PLUS_CNT_U7_S  0
+
+#define PCNT_INT_RAW_REG          (DR_REG_PCNT_BASE + 0x0080)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_RAW : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_RAW : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_RAW : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_RAW : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_RAW : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_RAW : RO ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_RAW : RO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_RAW : RO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_S  0
+
+#define PCNT_INT_ST_REG          (DR_REG_PCNT_BASE + 0x0084)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ST : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ST  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ST : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ST  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ST : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ST  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ST  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ST : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ST  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ST : RO; bitpos: [2]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U2_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ST    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_M  (PCNT_CNT_THR_EVENT_U2_INT_ST_V << PCNT_CNT_THR_EVENT_U2_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ST : RO; bitpos: [1]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U1_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ST    (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_M  (PCNT_CNT_THR_EVENT_U1_INT_ST_V << PCNT_CNT_THR_EVENT_U1_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ST : RO; bitpos: [0]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U0_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ST    (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_M  (PCNT_CNT_THR_EVENT_U0_INT_ST_V << PCNT_CNT_THR_EVENT_U0_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_S  0
+
+/* PCNT_INT_ENA_REG register
+ * Interrupt enable register
+ */
+
+#define PCNT_INT_ENA_REG          (DR_REG_PCNT_BASE + 0x0088)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ENA : R/W ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ENA : R/W ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ENA : R/W ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ENA : R/W ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ENA : R/W ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ENA : R/W ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_S  0
+
+#define PCNT_INT_CLR_REG          (DR_REG_PCNT_BASE + 0x008c)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_CLR : WO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel7 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_CLR : WO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel6 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_CLR : WO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel5 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_CLR : WO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel4 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_CLR : WO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel3 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_CLR : WO; bitpos: [2]; default: 0;
+ * Set this bit to clear the PCNT_CNT_THR_EVENT_U2_INT interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_M  (PCNT_CNT_THR_EVENT_U2_INT_CLR_V << PCNT_CNT_THR_EVENT_U2_INT_CLR_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_CLR : WO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel1 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_CLR : WO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel0 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_S  0
+
+#define PCNT_U0_STATUS_REG          (DR_REG_PCNT_BASE + 0x0090)
+
+/* PCNT_CORE_STATUS_U0 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U0  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_M  ((PCNT_CORE_STATUS_U0_V)<<(PCNT_CORE_STATUS_U0_S))
+#define PCNT_CORE_STATUS_U0_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_S  0
+
+/* 0: positive value to zero;
+ * 1: negative value to zero;
+ * 2: counter value negative;
+ * 3: counter value positive
+ */
+
+#define PCNT_STATUS_CNT_MODE    0x3
+#define PCNT_STATUS_CNT_MODE_M  ((PCNT_STATUS_CNT_MODE_V)<<(PCNT_STATUS_CNT_MODE_S))
+#define PCNT_STATUS_CNT_MODE_V  0x3
+#define PCNT_STATUS_CNT_MODE_S  0
+
+/* counter value equals to thresh1 */
+
+#define PCNT_STATUS_THRES1    BIT(2)
+#define PCNT_STATUS_THRES1_M  BIT(2)
+#define PCNT_STATUS_THRES1_V  0x1
+#define PCNT_STATUS_THRES1_S  2
+
+/* counter value equals to thresh0 */
+
+#define PCNT_STATUS_THRES0    BIT(3)
+#define PCNT_STATUS_THRES0_M  BIT(3)
+#define PCNT_STATUS_THRES0_V  0x1
+#define PCNT_STATUS_THRES0_S  3
+
+/* counter value reaches h_lim */
+
+#define PCNT_STATUS_L_LIM    BIT(4)
+#define PCNT_STATUS_L_LIM_M  BIT(4)
+#define PCNT_STATUS_L_LIM_V  0x1
+#define PCNT_STATUS_L_LIM_S  4
+
+/* counter value reaches l_lim */
+
+#define PCNT_STATUS_H_LIM    BIT(5)
+#define PCNT_STATUS_H_LIM_M  BIT(5)
+#define PCNT_STATUS_H_LIM_V  0x1
+#define PCNT_STATUS_H_LIM_S  5
+
+/* counter value equals to zero */
+
+#define PCNT_STATUS_ZERO    BIT(6)
+#define PCNT_STATUS_ZERO_M  BIT(6)
+#define PCNT_STATUS_ZERO_V  0x1
+#define PCNT_STATUS_ZERO_S  6
+
+#define PCNT_U1_STATUS_REG          (DR_REG_PCNT_BASE + 0x0094)
+
+/* PCNT_CORE_STATUS_U1 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U1  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_M  ((PCNT_CORE_STATUS_U1_V)<<(PCNT_CORE_STATUS_U1_S))
+#define PCNT_CORE_STATUS_U1_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_S  0
+
+#define PCNT_U2_STATUS_REG          (DR_REG_PCNT_BASE + 0x0098)
+
+/* PCNT_CORE_STATUS_U2 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U2  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_M  ((PCNT_CORE_STATUS_U2_V)<<(PCNT_CORE_STATUS_U2_S))
+#define PCNT_CORE_STATUS_U2_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_S  0
+
+#define PCNT_U3_STATUS_REG          (DR_REG_PCNT_BASE + 0x009c)
+
+/* PCNT_CORE_STATUS_U3 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U3  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_M  ((PCNT_CORE_STATUS_U3_V)<<(PCNT_CORE_STATUS_U3_S))
+#define PCNT_CORE_STATUS_U3_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_S  0
+
+#define PCNT_U4_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a0)
+/* PCNT_CORE_STATUS_U4 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U4  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_M  ((PCNT_CORE_STATUS_U4_V)<<(PCNT_CORE_STATUS_U4_S))
+#define PCNT_CORE_STATUS_U4_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_S  0
+
+#define PCNT_U5_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a4)
+/* PCNT_CORE_STATUS_U5 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U5  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_M  ((PCNT_CORE_STATUS_U5_V)<<(PCNT_CORE_STATUS_U5_S))
+#define PCNT_CORE_STATUS_U5_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_S  0
+
+#define PCNT_U6_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a8)
+/* PCNT_CORE_STATUS_U6 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U6  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_M  ((PCNT_CORE_STATUS_U6_V)<<(PCNT_CORE_STATUS_U6_S))
+#define PCNT_CORE_STATUS_U6_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_S  0
+
+#define PCNT_U7_STATUS_REG          (DR_REG_PCNT_BASE + 0x00ac)
+
+/* PCNT_CORE_STATUS_U7 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U7  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_M  ((PCNT_CORE_STATUS_U7_V)<<(PCNT_CORE_STATUS_U7_S))
+#define PCNT_CORE_STATUS_U7_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_S  0
+
+#define PCNT_CTRL_REG          (DR_REG_PCNT_BASE + 0x00b0)
+
+/* PCNT_CLK_EN : R/W ;bitpos:[16] ;default: 1'b0 ; */
+
+#define PCNT_CLK_EN  (BIT(16))
+#define PCNT_CLK_EN_M  (BIT(16))
+#define PCNT_CLK_EN_V  0x1
+#define PCNT_CLK_EN_S  16
+
+/* PCNT_CNT_PAUSE_U7 : R/W ;bitpos:[15] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit7's counter. */
+
+#define PCNT_CNT_PAUSE_U7  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_M  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_V  0x1
+#define PCNT_CNT_PAUSE_U7_S  15
+
+/* PCNT_PLUS_CNT_RST_U7 : R/W ;bitpos:[14] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit7's counter. */
+
+#define PCNT_PLUS_CNT_RST_U7  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_M  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_V  0x1
+#define PCNT_PLUS_CNT_RST_U7_S  14
+
+/* PCNT_CNT_PAUSE_U6 : R/W ;bitpos:[13] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit6's counter. */
+
+#define PCNT_CNT_PAUSE_U6  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_M  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_V  0x1
+#define PCNT_CNT_PAUSE_U6_S  13
+
+/* PCNT_PLUS_CNT_RST_U6 : R/W ;bitpos:[12] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit6's counter. */
+
+#define PCNT_PLUS_CNT_RST_U6  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_M  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_V  0x1
+#define PCNT_PLUS_CNT_RST_U6_S  12
+
+/* PCNT_CNT_PAUSE_U5 : R/W ;bitpos:[11] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit5's counter. */
+
+#define PCNT_CNT_PAUSE_U5  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_M  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_V  0x1
+#define PCNT_CNT_PAUSE_U5_S  11
+
+/* PCNT_PLUS_CNT_RST_U5 : R/W ;bitpos:[10] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit5's counter. */
+
+#define PCNT_PLUS_CNT_RST_U5  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_M  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_V  0x1
+#define PCNT_PLUS_CNT_RST_U5_S  10
+
+/* PCNT_CNT_PAUSE_U4 : R/W ;bitpos:[9] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit4's counter. */
+
+#define PCNT_CNT_PAUSE_U4  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_M  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_V  0x1
+#define PCNT_CNT_PAUSE_U4_S  9
+
+/* PCNT_PLUS_CNT_RST_U4 : R/W ;bitpos:[8] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit4's counter. */
+
+#define PCNT_PLUS_CNT_RST_U4  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_M  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_V  0x1
+#define PCNT_PLUS_CNT_RST_U4_S  8
+
+/* PCNT_CNT_PAUSE_U3 : R/W ;bitpos:[7] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit3's counter. */
+
+#define PCNT_CNT_PAUSE_U3  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_M  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_V  0x1
+#define PCNT_CNT_PAUSE_U3_S  7
+
+/* PCNT_PLUS_CNT_RST_U3 : R/W ;bitpos:[6] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit3's counter. */
+
+#define PCNT_PLUS_CNT_RST_U3  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_M  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_V  0x1
+#define PCNT_PLUS_CNT_RST_U3_S  6
+
+/* PCNT_CNT_PAUSE_U2 : R/W ;bitpos:[5] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit2's counter. */
+
+#define PCNT_CNT_PAUSE_U2  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_M  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_V  0x1
+#define PCNT_CNT_PAUSE_U2_S  5
+
+/* PCNT_PLUS_CNT_RST_U2 : R/W ;bitpos:[4] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit2's counter. */
+
+#define PCNT_PLUS_CNT_RST_U2  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_M  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_V  0x1
+#define PCNT_PLUS_CNT_RST_U2_S  4
+
+/* PCNT_CNT_PAUSE_U1 : R/W ;bitpos:[3] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit1's counter. */
+
+#define PCNT_CNT_PAUSE_U1  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_M  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_V  0x1
+#define PCNT_CNT_PAUSE_U1_S  3
+
+/* PCNT_PLUS_CNT_RST_U1 : R/W ;bitpos:[2] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit1's counter. */
+
+#define PCNT_PLUS_CNT_RST_U1  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_M  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_V  0x1
+#define PCNT_PLUS_CNT_RST_U1_S  2
+
+/* PCNT_CNT_PAUSE_U0 : R/W ;bitpos:[1] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit0's counter. */
+
+#define PCNT_CNT_PAUSE_U0  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_M  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_V  0x1
+#define PCNT_CNT_PAUSE_U0_S  1
+
+/* PCNT_PLUS_CNT_RST_U0 : R/W ;bitpos:[0] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit0's counter. */
+
+#define PCNT_PLUS_CNT_RST_U0  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_M  (BIT(0))

Review Comment:
   Ok, this is more difficult to fix, I will keep this way, since it is generated by regdesc tool



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] acassis commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996476912


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {1,2,3,4,5,6,7,8} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,

Review Comment:
   The comment is incorrect, I will fix it, thank you!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] pkarashchenko merged pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
pkarashchenko merged PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] pkarashchenko commented on a diff in pull request #7328: esp32: Add support to Quadrature Encoder

Posted by GitBox <gi...@apache.org>.
pkarashchenko commented on code in PR #7328:
URL: https://github.com/apache/incubator-nuttx/pull/7328#discussion_r996468602


##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {1,2,3,4,5,6,7,8} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,

Review Comment:
   minor: not needed



##########
boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c:
##########
@@ -398,6 +402,21 @@ int esp32_bringup(void)
     }
 #endif
 
+#ifdef CONFIG_SENSORS_QENCODER
+  /* Initialize and register the qencoder driver */
+
+#define PCNTID    0

Review Comment:
   let's move to board.h or some other board specific header.



##########
arch/xtensa/src/esp32/hardware/esp32_pcnt.h:
##########
@@ -0,0 +1,2495 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/hardware/esp32_pcnt.h
+ *
+ * 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_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+#define __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* PCNT_U0_CONF0_REG register
+ * Configuration register 0 for unit 0
+ */
+
+#define PCNT_U0_CONF0_REG (DR_REG_PCNT_BASE + 0x0)
+
+/* PCNT_CH1_LCTRL_MODE_U0 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_M  (PCNT_CH1_LCTRL_MODE_U0_V << PCNT_CH1_LCTRL_MODE_U0_S)
+#define PCNT_CH1_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U0 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_M  (PCNT_CH1_HCTRL_MODE_U0_V << PCNT_CH1_HCTRL_MODE_U0_S)
+#define PCNT_CH1_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_S  28
+
+/* PCNT_CH1_POS_MODE_U0 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U0    0x00000003
+#define PCNT_CH1_POS_MODE_U0_M  (PCNT_CH1_POS_MODE_U0_V << PCNT_CH1_POS_MODE_U0_S)
+#define PCNT_CH1_POS_MODE_U0_V  0x00000003
+#define PCNT_CH1_POS_MODE_U0_S  26
+
+/* PCNT_CH1_NEG_MODE_U0 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U0    0x00000003
+#define PCNT_CH1_NEG_MODE_U0_M  (PCNT_CH1_NEG_MODE_U0_V << PCNT_CH1_NEG_MODE_U0_S)
+#define PCNT_CH1_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U0_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U0 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_M  (PCNT_CH0_LCTRL_MODE_U0_V << PCNT_CH0_LCTRL_MODE_U0_S)
+#define PCNT_CH0_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U0 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_M  (PCNT_CH0_HCTRL_MODE_U0_V << PCNT_CH0_HCTRL_MODE_U0_S)
+#define PCNT_CH0_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_S  20
+
+/* PCNT_CH0_POS_MODE_U0 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U0    0x00000003
+#define PCNT_CH0_POS_MODE_U0_M  (PCNT_CH0_POS_MODE_U0_V << PCNT_CH0_POS_MODE_U0_S)
+#define PCNT_CH0_POS_MODE_U0_V  0x00000003
+#define PCNT_CH0_POS_MODE_U0_S  18
+
+/* PCNT_CH0_NEG_MODE_U0 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U0    0x00000003
+#define PCNT_CH0_NEG_MODE_U0_M  (PCNT_CH0_NEG_MODE_U0_V << PCNT_CH0_NEG_MODE_U0_S)
+#define PCNT_CH0_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U0_S  16
+
+/* PCNT_THR_THRES1_EN_U0 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 0's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U0    (BIT(15))
+#define PCNT_THR_THRES1_EN_U0_M  (PCNT_THR_THRES1_EN_U0_V << PCNT_THR_THRES1_EN_U0_S)
+#define PCNT_THR_THRES1_EN_U0_V  0x00000001
+#define PCNT_THR_THRES1_EN_U0_S  15
+
+/* PCNT_THR_THRES0_EN_U0 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 0's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U0    (BIT(14))
+#define PCNT_THR_THRES0_EN_U0_M  (PCNT_THR_THRES0_EN_U0_V << PCNT_THR_THRES0_EN_U0_S)
+#define PCNT_THR_THRES0_EN_U0_V  0x00000001
+#define PCNT_THR_THRES0_EN_U0_S  14
+
+/* PCNT_THR_L_LIM_EN_U0 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 0's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U0    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U0_M  (PCNT_THR_L_LIM_EN_U0_V << PCNT_THR_L_LIM_EN_U0_S)
+#define PCNT_THR_L_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U0_S  13
+
+/* PCNT_THR_H_LIM_EN_U0 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 0's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U0    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U0_M  (PCNT_THR_H_LIM_EN_U0_V << PCNT_THR_H_LIM_EN_U0_S)
+#define PCNT_THR_H_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U0_S  12
+
+/* PCNT_THR_ZERO_EN_U0 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 0's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U0    (BIT(11))
+#define PCNT_THR_ZERO_EN_U0_M  (PCNT_THR_ZERO_EN_U0_V << PCNT_THR_ZERO_EN_U0_S)
+#define PCNT_THR_ZERO_EN_U0_V  0x00000001
+#define PCNT_THR_ZERO_EN_U0_S  11
+
+/* PCNT_FILTER_EN_U0 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 0's input filter.
+ */
+
+#define PCNT_FILTER_EN_U0    (BIT(10))
+#define PCNT_FILTER_EN_U0_M  (PCNT_FILTER_EN_U0_V << PCNT_FILTER_EN_U0_S)
+#define PCNT_FILTER_EN_U0_V  0x00000001
+#define PCNT_FILTER_EN_U0_S  10
+
+/* PCNT_FILTER_THRES_U0 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U0    0x000003ff
+#define PCNT_FILTER_THRES_U0_M  (PCNT_FILTER_THRES_U0_V << PCNT_FILTER_THRES_U0_S)
+#define PCNT_FILTER_THRES_U0_V  0x000003ff
+#define PCNT_FILTER_THRES_U0_S  0
+
+/* PCNT_U0_CONF1_REG register
+ * Configuration register 1 for unit 0
+ */
+
+#define PCNT_U0_CONF1_REG (DR_REG_PCNT_BASE + 0x4)
+
+/* PCNT_CNT_THRES1_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES1_U0    0x0000ffff
+#define PCNT_CNT_THRES1_U0_M  (PCNT_CNT_THRES1_U0_V << PCNT_CNT_THRES1_U0_S)
+#define PCNT_CNT_THRES1_U0_V  0x0000ffff
+#define PCNT_CNT_THRES1_U0_S  16
+
+/* PCNT_CNT_THRES0_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES0_U0    0x0000ffff
+#define PCNT_CNT_THRES0_U0_M  (PCNT_CNT_THRES0_U0_V << PCNT_CNT_THRES0_U0_S)
+#define PCNT_CNT_THRES0_U0_V  0x0000ffff
+#define PCNT_CNT_THRES0_U0_S  0
+
+/* PCNT_U0_CONF2_REG register
+ * Configuration register 2 for unit 0
+ */
+
+#define PCNT_U0_CONF2_REG (DR_REG_PCNT_BASE + 0x8)
+
+/* PCNT_CNT_L_LIM_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 0.
+ */
+
+#define PCNT_CNT_L_LIM_U0    0x0000ffff
+#define PCNT_CNT_L_LIM_U0_M  (PCNT_CNT_L_LIM_U0_V << PCNT_CNT_L_LIM_U0_S)
+#define PCNT_CNT_L_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U0_S  16
+
+/* PCNT_CNT_H_LIM_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 0.
+ */
+
+#define PCNT_CNT_H_LIM_U0    0x0000ffff
+#define PCNT_CNT_H_LIM_U0_M  (PCNT_CNT_H_LIM_U0_V << PCNT_CNT_H_LIM_U0_S)
+#define PCNT_CNT_H_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U0_S  0
+
+/* PCNT_U1_CONF0_REG register
+ * Configuration register 0 for unit 1
+ */
+
+#define PCNT_U1_CONF0_REG (DR_REG_PCNT_BASE + 0xc)
+
+/* PCNT_CH1_LCTRL_MODE_U1 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_M  (PCNT_CH1_LCTRL_MODE_U1_V << PCNT_CH1_LCTRL_MODE_U1_S)
+#define PCNT_CH1_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U1 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_M  (PCNT_CH1_HCTRL_MODE_U1_V << PCNT_CH1_HCTRL_MODE_U1_S)
+#define PCNT_CH1_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_S  28
+
+/* PCNT_CH1_POS_MODE_U1 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U1    0x00000003
+#define PCNT_CH1_POS_MODE_U1_M  (PCNT_CH1_POS_MODE_U1_V << PCNT_CH1_POS_MODE_U1_S)
+#define PCNT_CH1_POS_MODE_U1_V  0x00000003
+#define PCNT_CH1_POS_MODE_U1_S  26
+
+/* PCNT_CH1_NEG_MODE_U1 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U1    0x00000003
+#define PCNT_CH1_NEG_MODE_U1_M  (PCNT_CH1_NEG_MODE_U1_V << PCNT_CH1_NEG_MODE_U1_S)
+#define PCNT_CH1_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U1_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U1 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_M  (PCNT_CH0_LCTRL_MODE_U1_V << PCNT_CH0_LCTRL_MODE_U1_S)
+#define PCNT_CH0_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U1 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_M  (PCNT_CH0_HCTRL_MODE_U1_V << PCNT_CH0_HCTRL_MODE_U1_S)
+#define PCNT_CH0_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_S  20
+
+/* PCNT_CH0_POS_MODE_U1 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U1    0x00000003
+#define PCNT_CH0_POS_MODE_U1_M  (PCNT_CH0_POS_MODE_U1_V << PCNT_CH0_POS_MODE_U1_S)
+#define PCNT_CH0_POS_MODE_U1_V  0x00000003
+#define PCNT_CH0_POS_MODE_U1_S  18
+
+/* PCNT_CH0_NEG_MODE_U1 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U1    0x00000003
+#define PCNT_CH0_NEG_MODE_U1_M  (PCNT_CH0_NEG_MODE_U1_V << PCNT_CH0_NEG_MODE_U1_S)
+#define PCNT_CH0_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U1_S  16
+
+/* PCNT_THR_THRES1_EN_U1 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 1's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U1    (BIT(15))
+#define PCNT_THR_THRES1_EN_U1_M  (PCNT_THR_THRES1_EN_U1_V << PCNT_THR_THRES1_EN_U1_S)
+#define PCNT_THR_THRES1_EN_U1_V  0x00000001
+#define PCNT_THR_THRES1_EN_U1_S  15
+
+/* PCNT_THR_THRES0_EN_U1 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 1's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U1    (BIT(14))
+#define PCNT_THR_THRES0_EN_U1_M  (PCNT_THR_THRES0_EN_U1_V << PCNT_THR_THRES0_EN_U1_S)
+#define PCNT_THR_THRES0_EN_U1_V  0x00000001
+#define PCNT_THR_THRES0_EN_U1_S  14
+
+/* PCNT_THR_L_LIM_EN_U1 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 1's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U1    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U1_M  (PCNT_THR_L_LIM_EN_U1_V << PCNT_THR_L_LIM_EN_U1_S)
+#define PCNT_THR_L_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U1_S  13
+
+/* PCNT_THR_H_LIM_EN_U1 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 1's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U1    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U1_M  (PCNT_THR_H_LIM_EN_U1_V << PCNT_THR_H_LIM_EN_U1_S)
+#define PCNT_THR_H_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U1_S  12
+
+/* PCNT_THR_ZERO_EN_U1 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 1's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U1    (BIT(11))
+#define PCNT_THR_ZERO_EN_U1_M  (PCNT_THR_ZERO_EN_U1_V << PCNT_THR_ZERO_EN_U1_S)
+#define PCNT_THR_ZERO_EN_U1_V  0x00000001
+#define PCNT_THR_ZERO_EN_U1_S  11
+
+/* PCNT_FILTER_EN_U1 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 1's input filter.
+ */
+
+#define PCNT_FILTER_EN_U1    (BIT(10))
+#define PCNT_FILTER_EN_U1_M  (PCNT_FILTER_EN_U1_V << PCNT_FILTER_EN_U1_S)
+#define PCNT_FILTER_EN_U1_V  0x00000001
+#define PCNT_FILTER_EN_U1_S  10
+
+/* PCNT_FILTER_THRES_U1 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U1    0x000003ff
+#define PCNT_FILTER_THRES_U1_M  (PCNT_FILTER_THRES_U1_V << PCNT_FILTER_THRES_U1_S)
+#define PCNT_FILTER_THRES_U1_V  0x000003ff
+#define PCNT_FILTER_THRES_U1_S  0
+
+/* PCNT_U1_CONF1_REG register
+ * Configuration register 1 for unit 1
+ */
+
+#define PCNT_U1_CONF1_REG (DR_REG_PCNT_BASE + 0x10)
+
+/* PCNT_CNT_THRES1_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES1_U1    0x0000ffff
+#define PCNT_CNT_THRES1_U1_M  (PCNT_CNT_THRES1_U1_V << PCNT_CNT_THRES1_U1_S)
+#define PCNT_CNT_THRES1_U1_V  0x0000ffff
+#define PCNT_CNT_THRES1_U1_S  16
+
+/* PCNT_CNT_THRES0_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES0_U1    0x0000ffff
+#define PCNT_CNT_THRES0_U1_M  (PCNT_CNT_THRES0_U1_V << PCNT_CNT_THRES0_U1_S)
+#define PCNT_CNT_THRES0_U1_V  0x0000ffff
+#define PCNT_CNT_THRES0_U1_S  0
+
+/* PCNT_U1_CONF2_REG register
+ * Configuration register 2 for unit 1
+ */
+
+#define PCNT_U1_CONF2_REG (DR_REG_PCNT_BASE + 0x14)
+
+/* PCNT_CNT_L_LIM_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 1.
+ */
+
+#define PCNT_CNT_L_LIM_U1    0x0000ffff
+#define PCNT_CNT_L_LIM_U1_M  (PCNT_CNT_L_LIM_U1_V << PCNT_CNT_L_LIM_U1_S)
+#define PCNT_CNT_L_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U1_S  16
+
+/* PCNT_CNT_H_LIM_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 1.
+ */
+
+#define PCNT_CNT_H_LIM_U1    0x0000ffff
+#define PCNT_CNT_H_LIM_U1_M  (PCNT_CNT_H_LIM_U1_V << PCNT_CNT_H_LIM_U1_S)
+#define PCNT_CNT_H_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U1_S  0
+
+/* PCNT_U2_CONF0_REG register
+ * Configuration register 0 for unit 2
+ */
+
+#define PCNT_U2_CONF0_REG (DR_REG_PCNT_BASE + 0x18)
+
+/* PCNT_CH1_LCTRL_MODE_U2 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_M  (PCNT_CH1_LCTRL_MODE_U2_V << PCNT_CH1_LCTRL_MODE_U2_S)
+#define PCNT_CH1_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U2 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_M  (PCNT_CH1_HCTRL_MODE_U2_V << PCNT_CH1_HCTRL_MODE_U2_S)
+#define PCNT_CH1_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_S  28
+
+/* PCNT_CH1_POS_MODE_U2 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U2    0x00000003
+#define PCNT_CH1_POS_MODE_U2_M  (PCNT_CH1_POS_MODE_U2_V << PCNT_CH1_POS_MODE_U2_S)
+#define PCNT_CH1_POS_MODE_U2_V  0x00000003
+#define PCNT_CH1_POS_MODE_U2_S  26
+
+/* PCNT_CH1_NEG_MODE_U2 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U2    0x00000003
+#define PCNT_CH1_NEG_MODE_U2_M  (PCNT_CH1_NEG_MODE_U2_V << PCNT_CH1_NEG_MODE_U2_S)
+#define PCNT_CH1_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U2_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U2 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_M  (PCNT_CH0_LCTRL_MODE_U2_V << PCNT_CH0_LCTRL_MODE_U2_S)
+#define PCNT_CH0_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U2 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_M  (PCNT_CH0_HCTRL_MODE_U2_V << PCNT_CH0_HCTRL_MODE_U2_S)
+#define PCNT_CH0_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_S  20
+
+/* PCNT_CH0_POS_MODE_U2 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U2    0x00000003
+#define PCNT_CH0_POS_MODE_U2_M  (PCNT_CH0_POS_MODE_U2_V << PCNT_CH0_POS_MODE_U2_S)
+#define PCNT_CH0_POS_MODE_U2_V  0x00000003
+#define PCNT_CH0_POS_MODE_U2_S  18
+
+/* PCNT_CH0_NEG_MODE_U2 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U2    0x00000003
+#define PCNT_CH0_NEG_MODE_U2_M  (PCNT_CH0_NEG_MODE_U2_V << PCNT_CH0_NEG_MODE_U2_S)
+#define PCNT_CH0_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U2_S  16
+
+/* PCNT_THR_THRES1_EN_U2 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 2's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U2    (BIT(15))
+#define PCNT_THR_THRES1_EN_U2_M  (PCNT_THR_THRES1_EN_U2_V << PCNT_THR_THRES1_EN_U2_S)
+#define PCNT_THR_THRES1_EN_U2_V  0x00000001
+#define PCNT_THR_THRES1_EN_U2_S  15
+
+/* PCNT_THR_THRES0_EN_U2 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 2's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U2    (BIT(14))
+#define PCNT_THR_THRES0_EN_U2_M  (PCNT_THR_THRES0_EN_U2_V << PCNT_THR_THRES0_EN_U2_S)
+#define PCNT_THR_THRES0_EN_U2_V  0x00000001
+#define PCNT_THR_THRES0_EN_U2_S  14
+
+/* PCNT_THR_L_LIM_EN_U2 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 2's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U2    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U2_M  (PCNT_THR_L_LIM_EN_U2_V << PCNT_THR_L_LIM_EN_U2_S)
+#define PCNT_THR_L_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U2_S  13
+
+/* PCNT_THR_H_LIM_EN_U2 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 2's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U2    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U2_M  (PCNT_THR_H_LIM_EN_U2_V << PCNT_THR_H_LIM_EN_U2_S)
+#define PCNT_THR_H_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U2_S  12
+
+/* PCNT_THR_ZERO_EN_U2 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 2's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U2    (BIT(11))
+#define PCNT_THR_ZERO_EN_U2_M  (PCNT_THR_ZERO_EN_U2_V << PCNT_THR_ZERO_EN_U2_S)
+#define PCNT_THR_ZERO_EN_U2_V  0x00000001
+#define PCNT_THR_ZERO_EN_U2_S  11
+
+/* PCNT_FILTER_EN_U2 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 2's input filter.
+ */
+
+#define PCNT_FILTER_EN_U2    (BIT(10))
+#define PCNT_FILTER_EN_U2_M  (PCNT_FILTER_EN_U2_V << PCNT_FILTER_EN_U2_S)
+#define PCNT_FILTER_EN_U2_V  0x00000001
+#define PCNT_FILTER_EN_U2_S  10
+
+/* PCNT_FILTER_THRES_U2 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U2    0x000003ff
+#define PCNT_FILTER_THRES_U2_M  (PCNT_FILTER_THRES_U2_V << PCNT_FILTER_THRES_U2_S)
+#define PCNT_FILTER_THRES_U2_V  0x000003ff
+#define PCNT_FILTER_THRES_U2_S  0
+
+/* PCNT_U2_CONF1_REG register
+ * Configuration register 1 for unit 2
+ */
+
+#define PCNT_U2_CONF1_REG (DR_REG_PCNT_BASE + 0x1c)
+
+/* PCNT_CNT_THRES1_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES1_U2    0x0000ffff
+#define PCNT_CNT_THRES1_U2_M  (PCNT_CNT_THRES1_U2_V << PCNT_CNT_THRES1_U2_S)
+#define PCNT_CNT_THRES1_U2_V  0x0000ffff
+#define PCNT_CNT_THRES1_U2_S  16
+
+/* PCNT_CNT_THRES0_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES0_U2    0x0000ffff
+#define PCNT_CNT_THRES0_U2_M  (PCNT_CNT_THRES0_U2_V << PCNT_CNT_THRES0_U2_S)
+#define PCNT_CNT_THRES0_U2_V  0x0000ffff
+#define PCNT_CNT_THRES0_U2_S  0
+
+/* PCNT_U2_CONF2_REG register
+ * Configuration register 2 for unit 2
+ */
+
+#define PCNT_U2_CONF2_REG (DR_REG_PCNT_BASE + 0x20)
+
+/* PCNT_CNT_L_LIM_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 2.
+ */
+
+#define PCNT_CNT_L_LIM_U2    0x0000ffff
+#define PCNT_CNT_L_LIM_U2_M  (PCNT_CNT_L_LIM_U2_V << PCNT_CNT_L_LIM_U2_S)
+#define PCNT_CNT_L_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U2_S  16
+
+/* PCNT_CNT_H_LIM_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 2.
+ */
+
+#define PCNT_CNT_H_LIM_U2    0x0000ffff
+#define PCNT_CNT_H_LIM_U2_M  (PCNT_CNT_H_LIM_U2_V << PCNT_CNT_H_LIM_U2_S)
+#define PCNT_CNT_H_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U2_S  0
+
+/* PCNT_U3_CONF0_REG register
+ * Configuration register 0 for unit 3
+ */
+
+#define PCNT_U3_CONF0_REG (DR_REG_PCNT_BASE + 0x24)
+
+/* PCNT_CH1_LCTRL_MODE_U3 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_M  (PCNT_CH1_LCTRL_MODE_U3_V << PCNT_CH1_LCTRL_MODE_U3_S)
+#define PCNT_CH1_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U3 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_M  (PCNT_CH1_HCTRL_MODE_U3_V << PCNT_CH1_HCTRL_MODE_U3_S)
+#define PCNT_CH1_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_S  28
+
+/* PCNT_CH1_POS_MODE_U3 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U3    0x00000003
+#define PCNT_CH1_POS_MODE_U3_M  (PCNT_CH1_POS_MODE_U3_V << PCNT_CH1_POS_MODE_U3_S)
+#define PCNT_CH1_POS_MODE_U3_V  0x00000003
+#define PCNT_CH1_POS_MODE_U3_S  26
+
+/* PCNT_CH1_NEG_MODE_U3 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U3    0x00000003
+#define PCNT_CH1_NEG_MODE_U3_M  (PCNT_CH1_NEG_MODE_U3_V << PCNT_CH1_NEG_MODE_U3_S)
+#define PCNT_CH1_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U3_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U3 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_M  (PCNT_CH0_LCTRL_MODE_U3_V << PCNT_CH0_LCTRL_MODE_U3_S)
+#define PCNT_CH0_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U3 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_M  (PCNT_CH0_HCTRL_MODE_U3_V << PCNT_CH0_HCTRL_MODE_U3_S)
+#define PCNT_CH0_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_S  20
+
+/* PCNT_CH0_POS_MODE_U3 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U3    0x00000003
+#define PCNT_CH0_POS_MODE_U3_M  (PCNT_CH0_POS_MODE_U3_V << PCNT_CH0_POS_MODE_U3_S)
+#define PCNT_CH0_POS_MODE_U3_V  0x00000003
+#define PCNT_CH0_POS_MODE_U3_S  18
+
+/* PCNT_CH0_NEG_MODE_U3 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U3    0x00000003
+#define PCNT_CH0_NEG_MODE_U3_M  (PCNT_CH0_NEG_MODE_U3_V << PCNT_CH0_NEG_MODE_U3_S)
+#define PCNT_CH0_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U3_S  16
+
+/* PCNT_THR_THRES1_EN_U3 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 3's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U3    (BIT(15))
+#define PCNT_THR_THRES1_EN_U3_M  (PCNT_THR_THRES1_EN_U3_V << PCNT_THR_THRES1_EN_U3_S)
+#define PCNT_THR_THRES1_EN_U3_V  0x00000001
+#define PCNT_THR_THRES1_EN_U3_S  15
+
+/* PCNT_THR_THRES0_EN_U3 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 3's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U3    (BIT(14))
+#define PCNT_THR_THRES0_EN_U3_M  (PCNT_THR_THRES0_EN_U3_V << PCNT_THR_THRES0_EN_U3_S)
+#define PCNT_THR_THRES0_EN_U3_V  0x00000001
+#define PCNT_THR_THRES0_EN_U3_S  14
+
+/* PCNT_THR_L_LIM_EN_U3 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 3's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U3    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U3_M  (PCNT_THR_L_LIM_EN_U3_V << PCNT_THR_L_LIM_EN_U3_S)
+#define PCNT_THR_L_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U3_S  13
+
+/* PCNT_THR_H_LIM_EN_U3 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 3's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U3    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U3_M  (PCNT_THR_H_LIM_EN_U3_V << PCNT_THR_H_LIM_EN_U3_S)
+#define PCNT_THR_H_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U3_S  12
+
+/* PCNT_THR_ZERO_EN_U3 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 3's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U3    (BIT(11))
+#define PCNT_THR_ZERO_EN_U3_M  (PCNT_THR_ZERO_EN_U3_V << PCNT_THR_ZERO_EN_U3_S)
+#define PCNT_THR_ZERO_EN_U3_V  0x00000001
+#define PCNT_THR_ZERO_EN_U3_S  11
+
+/* PCNT_FILTER_EN_U3 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 3's input filter.
+ */
+
+#define PCNT_FILTER_EN_U3    (BIT(10))
+#define PCNT_FILTER_EN_U3_M  (PCNT_FILTER_EN_U3_V << PCNT_FILTER_EN_U3_S)
+#define PCNT_FILTER_EN_U3_V  0x00000001
+#define PCNT_FILTER_EN_U3_S  10
+
+/* PCNT_FILTER_THRES_U3 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U3    0x000003ff
+#define PCNT_FILTER_THRES_U3_M  (PCNT_FILTER_THRES_U3_V << PCNT_FILTER_THRES_U3_S)
+#define PCNT_FILTER_THRES_U3_V  0x000003ff
+#define PCNT_FILTER_THRES_U3_S  0
+
+/* PCNT_U3_CONF1_REG register
+ * Configuration register 1 for unit 3
+ */
+
+#define PCNT_U3_CONF1_REG (DR_REG_PCNT_BASE + 0x28)
+
+/* PCNT_CNT_THRES1_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES1_U3    0x0000ffff
+#define PCNT_CNT_THRES1_U3_M  (PCNT_CNT_THRES1_U3_V << PCNT_CNT_THRES1_U3_S)
+#define PCNT_CNT_THRES1_U3_V  0x0000ffff
+#define PCNT_CNT_THRES1_U3_S  16
+
+/* PCNT_CNT_THRES0_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES0_U3    0x0000ffff
+#define PCNT_CNT_THRES0_U3_M  (PCNT_CNT_THRES0_U3_V << PCNT_CNT_THRES0_U3_S)
+#define PCNT_CNT_THRES0_U3_V  0x0000ffff
+#define PCNT_CNT_THRES0_U3_S  0
+
+/* PCNT_U3_CONF2_REG register
+ * Configuration register 2 for unit 3
+ */
+
+#define PCNT_U3_CONF2_REG (DR_REG_PCNT_BASE + 0x2c)
+
+/* PCNT_CNT_L_LIM_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 3.
+ */
+
+#define PCNT_CNT_L_LIM_U3    0x0000ffff
+#define PCNT_CNT_L_LIM_U3_M  (PCNT_CNT_L_LIM_U3_V << PCNT_CNT_L_LIM_U3_S)
+#define PCNT_CNT_L_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U3_S  16
+
+/* PCNT_CNT_H_LIM_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 3.
+ */
+
+#define PCNT_CNT_H_LIM_U3    0x0000ffff
+#define PCNT_CNT_H_LIM_U3_M  (PCNT_CNT_H_LIM_U3_V << PCNT_CNT_H_LIM_U3_S)
+#define PCNT_CNT_H_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U3_S  0
+
+#define PCNT_U4_CONF0_REG          (DR_REG_PCNT_BASE + 0x0030)
+
+/* PCNT_CH1_LCTRL_MODE_U4 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U4_M  ((PCNT_CH1_LCTRL_MODE_U4_V)<<(PCNT_CH1_LCTRL_MODE_U4_S))
+#define PCNT_CH1_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U4_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U4 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U4_M  ((PCNT_CH1_HCTRL_MODE_U4_V)<<(PCNT_CH1_HCTRL_MODE_U4_S))
+#define PCNT_CH1_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U4_S  28
+
+/* PCNT_CH1_POS_MODE_U4 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U4  0x00000003
+#define PCNT_CH1_POS_MODE_U4_M  ((PCNT_CH1_POS_MODE_U4_V)<<(PCNT_CH1_POS_MODE_U4_S))
+#define PCNT_CH1_POS_MODE_U4_V  0x3
+#define PCNT_CH1_POS_MODE_U4_S  26
+
+/* PCNT_CH1_NEG_MODE_U4 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U4  0x00000003
+#define PCNT_CH1_NEG_MODE_U4_M  ((PCNT_CH1_NEG_MODE_U4_V)<<(PCNT_CH1_NEG_MODE_U4_S))
+#define PCNT_CH1_NEG_MODE_U4_V  0x3
+#define PCNT_CH1_NEG_MODE_U4_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U4 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U4_M  ((PCNT_CH0_LCTRL_MODE_U4_V)<<(PCNT_CH0_LCTRL_MODE_U4_S))
+#define PCNT_CH0_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U4_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U4 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U4_M  ((PCNT_CH0_HCTRL_MODE_U4_V)<<(PCNT_CH0_HCTRL_MODE_U4_S))
+#define PCNT_CH0_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U4_S  20
+
+/* PCNT_CH0_POS_MODE_U4 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U4  0x00000003
+#define PCNT_CH0_POS_MODE_U4_M  ((PCNT_CH0_POS_MODE_U4_V)<<(PCNT_CH0_POS_MODE_U4_S))
+#define PCNT_CH0_POS_MODE_U4_V  0x3
+#define PCNT_CH0_POS_MODE_U4_S  18
+
+/* PCNT_CH0_NEG_MODE_U4 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U4  0x00000003
+#define PCNT_CH0_NEG_MODE_U4_M  ((PCNT_CH0_NEG_MODE_U4_V)<<(PCNT_CH0_NEG_MODE_U4_S))
+#define PCNT_CH0_NEG_MODE_U4_V  0x3
+#define PCNT_CH0_NEG_MODE_U4_S  16
+
+/* PCNT_THR_THRES1_EN_U4 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U4  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_V  0x1
+#define PCNT_THR_THRES1_EN_U4_S  15
+
+/* PCNT_THR_THRES0_EN_U4 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U4  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_V  0x1
+#define PCNT_THR_THRES0_EN_U4_S  14
+
+/* PCNT_THR_L_LIM_EN_U4 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_l_lim  value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U4  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_V  0x1
+#define PCNT_THR_L_LIM_EN_U4_S  13
+
+/* PCNT_THR_H_LIM_EN_U4 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U4  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_V  0x1
+#define PCNT_THR_H_LIM_EN_U4_S  12
+
+/* PCNT_THR_ZERO_EN_U4 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U4  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_V  0x1
+#define PCNT_THR_ZERO_EN_U4_S  11
+
+/* PCNT_FILTER_EN_U4 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit4.
+ */
+
+#define PCNT_FILTER_EN_U4  (BIT(10))
+#define PCNT_FILTER_EN_U4_M  (BIT(10))
+#define PCNT_FILTER_EN_U4_V  0x1
+#define PCNT_FILTER_EN_U4_S  10
+
+/* PCNT_FILTER_THRES_U4 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit4.
+ */
+
+#define PCNT_FILTER_THRES_U4  0x000003FF
+#define PCNT_FILTER_THRES_U4_M  ((PCNT_FILTER_THRES_U4_V)<<(PCNT_FILTER_THRES_U4_S))
+#define PCNT_FILTER_THRES_U4_V  0x3FF
+#define PCNT_FILTER_THRES_U4_S  0
+
+#define PCNT_U4_CONF1_REG          (DR_REG_PCNT_BASE + 0x0034)
+
+/* PCNT_CNT_THRES1_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure thres1 value for unit4.
+ */
+
+#define PCNT_CNT_THRES1_U4  0x0000FFFF
+#define PCNT_CNT_THRES1_U4_M  ((PCNT_CNT_THRES1_U4_V)<<(PCNT_CNT_THRES1_U4_S))
+#define PCNT_CNT_THRES1_U4_V  0xFFFF
+#define PCNT_CNT_THRES1_U4_S  16
+
+/* PCNT_CNT_THRES0_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit4.
+ */
+
+#define PCNT_CNT_THRES0_U4  0x0000FFFF
+#define PCNT_CNT_THRES0_U4_M  ((PCNT_CNT_THRES0_U4_V)<<(PCNT_CNT_THRES0_U4_S))
+#define PCNT_CNT_THRES0_U4_V  0xFFFF
+#define PCNT_CNT_THRES0_U4_S  0
+
+#define PCNT_U4_CONF2_REG          (DR_REG_PCNT_BASE + 0x0038)
+
+/* PCNT_CNT_L_LIM_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit4.
+ */
+
+#define PCNT_CNT_L_LIM_U4  0x0000FFFF
+#define PCNT_CNT_L_LIM_U4_M  ((PCNT_CNT_L_LIM_U4_V)<<(PCNT_CNT_L_LIM_U4_S))
+#define PCNT_CNT_L_LIM_U4_V  0xFFFF
+#define PCNT_CNT_L_LIM_U4_S  16
+
+/* PCNT_CNT_H_LIM_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit4.
+ */
+
+#define PCNT_CNT_H_LIM_U4  0x0000FFFF
+#define PCNT_CNT_H_LIM_U4_M  ((PCNT_CNT_H_LIM_U4_V)<<(PCNT_CNT_H_LIM_U4_S))
+#define PCNT_CNT_H_LIM_U4_V  0xFFFF
+#define PCNT_CNT_H_LIM_U4_S  0
+
+#define PCNT_U5_CONF0_REG          (DR_REG_PCNT_BASE + 0x003c)
+
+/* PCNT_CH1_LCTRL_MODE_U5 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U5_M  ((PCNT_CH1_LCTRL_MODE_U5_V)<<(PCNT_CH1_LCTRL_MODE_U5_S))
+#define PCNT_CH1_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U5_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U5 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U5_M  ((PCNT_CH1_HCTRL_MODE_U5_V)<<(PCNT_CH1_HCTRL_MODE_U5_S))
+#define PCNT_CH1_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U5_S  28
+
+/* PCNT_CH1_POS_MODE_U5 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U5  0x00000003
+#define PCNT_CH1_POS_MODE_U5_M  ((PCNT_CH1_POS_MODE_U5_V)<<(PCNT_CH1_POS_MODE_U5_S))
+#define PCNT_CH1_POS_MODE_U5_V  0x3
+#define PCNT_CH1_POS_MODE_U5_S  26
+
+/* PCNT_CH1_NEG_MODE_U5 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U5  0x00000003
+#define PCNT_CH1_NEG_MODE_U5_M  ((PCNT_CH1_NEG_MODE_U5_V)<<(PCNT_CH1_NEG_MODE_U5_S))
+#define PCNT_CH1_NEG_MODE_U5_V  0x3
+#define PCNT_CH1_NEG_MODE_U5_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U5 : R/W ;bitpos:[23:22] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U5_M  ((PCNT_CH0_LCTRL_MODE_U5_V)<<(PCNT_CH0_LCTRL_MODE_U5_S))
+#define PCNT_CH0_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U5_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U5 : R/W ;bitpos:[21:20] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's high
+ * control signal for unit5.
+ * 0:increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U5_M  ((PCNT_CH0_HCTRL_MODE_U5_V)<<(PCNT_CH0_HCTRL_MODE_U5_S))
+#define PCNT_CH0_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U5_S  20
+
+/* PCNT_CH0_POS_MODE_U5 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U5  0x00000003
+#define PCNT_CH0_POS_MODE_U5_M  ((PCNT_CH0_POS_MODE_U5_V)<<(PCNT_CH0_POS_MODE_U5_S))
+#define PCNT_CH0_POS_MODE_U5_V  0x3
+#define PCNT_CH0_POS_MODE_U5_S  18
+
+/* PCNT_CH0_NEG_MODE_U5 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U5  0x00000003
+#define PCNT_CH0_NEG_MODE_U5_M  ((PCNT_CH0_NEG_MODE_U5_V)<<(PCNT_CH0_NEG_MODE_U5_S))
+#define PCNT_CH0_NEG_MODE_U5_V  0x3
+#define PCNT_CH0_NEG_MODE_U5_S  16
+
+/* PCNT_THR_THRES1_EN_U5 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U5  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_V  0x1
+#define PCNT_THR_THRES1_EN_U5_S  15
+
+/* PCNT_THR_THRES0_EN_U5 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U5  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_V  0x1
+#define PCNT_THR_THRES0_EN_U5_S  14
+
+/* PCNT_THR_L_LIM_EN_U5 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U5  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_V  0x1
+#define PCNT_THR_L_LIM_EN_U5_S  13
+
+/* PCNT_THR_H_LIM_EN_U5 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U5  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_V  0x1
+#define PCNT_THR_H_LIM_EN_U5_S  12
+
+/* PCNT_THR_ZERO_EN_U5 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U5  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_V  0x1
+#define PCNT_THR_ZERO_EN_U5_S  11
+
+/* PCNT_FILTER_EN_U5 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit5.
+ */
+
+#define PCNT_FILTER_EN_U5  (BIT(10))
+#define PCNT_FILTER_EN_U5_M  (BIT(10))
+#define PCNT_FILTER_EN_U5_V  0x1
+#define PCNT_FILTER_EN_U5_S  10
+
+/* PCNT_FILTER_THRES_U5 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit5.
+ */
+
+#define PCNT_FILTER_THRES_U5  0x000003FF
+#define PCNT_FILTER_THRES_U5_M  ((PCNT_FILTER_THRES_U5_V)<<(PCNT_FILTER_THRES_U5_S))
+#define PCNT_FILTER_THRES_U5_V  0x3FF
+#define PCNT_FILTER_THRES_U5_S  0
+
+#define PCNT_U5_CONF1_REG          (DR_REG_PCNT_BASE + 0x0040)
+
+/* PCNT_CNT_THRES1_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit5.
+ */
+
+#define PCNT_CNT_THRES1_U5  0x0000FFFF
+#define PCNT_CNT_THRES1_U5_M  ((PCNT_CNT_THRES1_U5_V)<<(PCNT_CNT_THRES1_U5_S))
+#define PCNT_CNT_THRES1_U5_V  0xFFFF
+#define PCNT_CNT_THRES1_U5_S  16
+
+/* PCNT_CNT_THRES0_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit5.
+ */
+
+#define PCNT_CNT_THRES0_U5  0x0000FFFF
+#define PCNT_CNT_THRES0_U5_M  ((PCNT_CNT_THRES0_U5_V)<<(PCNT_CNT_THRES0_U5_S))
+#define PCNT_CNT_THRES0_U5_V  0xFFFF
+#define PCNT_CNT_THRES0_U5_S  0
+
+#define PCNT_U5_CONF2_REG          (DR_REG_PCNT_BASE + 0x0044)
+
+/* PCNT_CNT_L_LIM_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit5.
+ */
+
+#define PCNT_CNT_L_LIM_U5  0x0000FFFF
+#define PCNT_CNT_L_LIM_U5_M  ((PCNT_CNT_L_LIM_U5_V)<<(PCNT_CNT_L_LIM_U5_S))
+#define PCNT_CNT_L_LIM_U5_V  0xFFFF
+#define PCNT_CNT_L_LIM_U5_S  16
+
+/* PCNT_CNT_H_LIM_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit5.
+ */
+
+#define PCNT_CNT_H_LIM_U5  0x0000FFFF
+#define PCNT_CNT_H_LIM_U5_M  ((PCNT_CNT_H_LIM_U5_V)<<(PCNT_CNT_H_LIM_U5_S))
+#define PCNT_CNT_H_LIM_U5_V  0xFFFF
+#define PCNT_CNT_H_LIM_U5_S  0
+
+#define PCNT_U6_CONF0_REG          (DR_REG_PCNT_BASE + 0x0048)
+
+/* PCNT_CH1_LCTRL_MODE_U6 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * low control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U6_M  ((PCNT_CH1_LCTRL_MODE_U6_V)<<(PCNT_CH1_LCTRL_MODE_U6_S))
+#define PCNT_CH1_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U6_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U6 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U6_M  ((PCNT_CH1_HCTRL_MODE_U6_V)<<(PCNT_CH1_HCTRL_MODE_U6_S))
+#define PCNT_CH1_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U6_S  28
+
+/* PCNT_CH1_POS_MODE_U6 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U6  0x00000003
+#define PCNT_CH1_POS_MODE_U6_M  ((PCNT_CH1_POS_MODE_U6_V)<<(PCNT_CH1_POS_MODE_U6_S))
+#define PCNT_CH1_POS_MODE_U6_V  0x3
+#define PCNT_CH1_POS_MODE_U6_S  26
+
+/* PCNT_CH1_NEG_MODE_U6 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * input negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U6  0x00000003
+#define PCNT_CH1_NEG_MODE_U6_M  ((PCNT_CH1_NEG_MODE_U6_V)<<(PCNT_CH1_NEG_MODE_U6_S))
+#define PCNT_CH1_NEG_MODE_U6_V  0x3
+#define PCNT_CH1_NEG_MODE_U6_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U6 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U6_M  ((PCNT_CH0_LCTRL_MODE_U6_V)<<(PCNT_CH0_LCTRL_MODE_U6_S))
+#define PCNT_CH0_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U6_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U6 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * high control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U6_M  ((PCNT_CH0_HCTRL_MODE_U6_V)<<(PCNT_CH0_HCTRL_MODE_U6_S))
+#define PCNT_CH0_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U6_S  20
+
+/* PCNT_CH0_POS_MODE_U6 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U6  0x00000003
+#define PCNT_CH0_POS_MODE_U6_M  ((PCNT_CH0_POS_MODE_U6_V)<<(PCNT_CH0_POS_MODE_U6_S))
+#define PCNT_CH0_POS_MODE_U6_V  0x3
+#define PCNT_CH0_POS_MODE_U6_S  18
+
+/* PCNT_CH0_NEG_MODE_U6 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U6  0x00000003
+#define PCNT_CH0_NEG_MODE_U6_M  ((PCNT_CH0_NEG_MODE_U6_V)<<(PCNT_CH0_NEG_MODE_U6_S))
+#define PCNT_CH0_NEG_MODE_U6_V  0x3
+#define PCNT_CH0_NEG_MODE_U6_S  16
+
+/* PCNT_THR_THRES1_EN_U6 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit6's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U6  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_V  0x1
+#define PCNT_THR_THRES1_EN_U6_S  15
+
+/* PCNT_THR_THRES0_EN_U6 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U6  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_V  0x1
+#define PCNT_THR_THRES0_EN_U6_S  14
+
+/* PCNT_THR_L_LIM_EN_U6 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U6  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_V  0x1
+#define PCNT_THR_L_LIM_EN_U6_S  13
+
+/* PCNT_THR_H_LIM_EN_U6 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit6's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U6  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_V  0x1
+#define PCNT_THR_H_LIM_EN_U6_S  12
+
+/* PCNT_THR_ZERO_EN_U6 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U6  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_V  0x1
+#define PCNT_THR_ZERO_EN_U6_S  11
+
+/* PCNT_FILTER_EN_U6 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit6.
+ */
+
+#define PCNT_FILTER_EN_U6  (BIT(10))
+#define PCNT_FILTER_EN_U6_M  (BIT(10))
+#define PCNT_FILTER_EN_U6_V  0x1
+#define PCNT_FILTER_EN_U6_S  10
+
+/* PCNT_FILTER_THRES_U6 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is
+ * smaller than this value for unit6.
+ */
+
+#define PCNT_FILTER_THRES_U6  0x000003FF
+#define PCNT_FILTER_THRES_U6_M  ((PCNT_FILTER_THRES_U6_V)<<(PCNT_FILTER_THRES_U6_S))
+#define PCNT_FILTER_THRES_U6_V  0x3FF
+#define PCNT_FILTER_THRES_U6_S  0
+
+#define PCNT_U6_CONF1_REG          (DR_REG_PCNT_BASE + 0x004c)
+
+/* PCNT_CNT_THRES1_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit6.
+ */
+
+#define PCNT_CNT_THRES1_U6  0x0000FFFF
+#define PCNT_CNT_THRES1_U6_M  ((PCNT_CNT_THRES1_U6_V)<<(PCNT_CNT_THRES1_U6_S))
+#define PCNT_CNT_THRES1_U6_V  0xFFFF
+#define PCNT_CNT_THRES1_U6_S  16
+
+/* PCNT_CNT_THRES0_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit6.
+ */
+
+#define PCNT_CNT_THRES0_U6  0x0000FFFF
+#define PCNT_CNT_THRES0_U6_M  ((PCNT_CNT_THRES0_U6_V)<<(PCNT_CNT_THRES0_U6_S))
+#define PCNT_CNT_THRES0_U6_V  0xFFFF
+#define PCNT_CNT_THRES0_U6_S  0
+
+#define PCNT_U6_CONF2_REG          (DR_REG_PCNT_BASE + 0x0050)
+
+/* PCNT_CNT_L_LIM_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit6.
+ */
+
+#define PCNT_CNT_L_LIM_U6  0x0000FFFF
+#define PCNT_CNT_L_LIM_U6_M  ((PCNT_CNT_L_LIM_U6_V)<<(PCNT_CNT_L_LIM_U6_S))
+#define PCNT_CNT_L_LIM_U6_V  0xFFFF
+#define PCNT_CNT_L_LIM_U6_S  16
+
+/* PCNT_CNT_H_LIM_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit6.
+ */
+
+#define PCNT_CNT_H_LIM_U6  0x0000FFFF
+#define PCNT_CNT_H_LIM_U6_M  ((PCNT_CNT_H_LIM_U6_V)<<(PCNT_CNT_H_LIM_U6_S))
+#define PCNT_CNT_H_LIM_U6_V  0xFFFF
+#define PCNT_CNT_H_LIM_U6_S  0
+
+#define PCNT_U7_CONF0_REG          (DR_REG_PCNT_BASE + 0x0054)
+
+/* PCNT_CH1_LCTRL_MODE_U7 : R/W ;bitpos:[31:30] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U7_M  ((PCNT_CH1_LCTRL_MODE_U7_V)<<(PCNT_CH1_LCTRL_MODE_U7_S))
+#define PCNT_CH1_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U7_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U7 : R/W ;bitpos:[29:28] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U7_M  ((PCNT_CH1_HCTRL_MODE_U7_V)<<(PCNT_CH1_HCTRL_MODE_U7_S))
+#define PCNT_CH1_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U7_S  28
+
+/* PCNT_CH1_POS_MODE_U7 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2:decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U7  0x00000003
+#define PCNT_CH1_POS_MODE_U7_M  ((PCNT_CH1_POS_MODE_U7_V)<<(PCNT_CH1_POS_MODE_U7_S))
+#define PCNT_CH1_POS_MODE_U7_V  0x3
+#define PCNT_CH1_POS_MODE_U7_S  26
+
+/* PCNT_CH1_NEG_MODE_U7 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U7  0x00000003
+#define PCNT_CH1_NEG_MODE_U7_M  ((PCNT_CH1_NEG_MODE_U7_V)<<(PCNT_CH1_NEG_MODE_U7_S))
+#define PCNT_CH1_NEG_MODE_U7_V  0x3
+#define PCNT_CH1_NEG_MODE_U7_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U7 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U7_M  ((PCNT_CH0_LCTRL_MODE_U7_V)<<(PCNT_CH0_LCTRL_MODE_U7_S))
+#define PCNT_CH0_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U7_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U7 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U7_M  ((PCNT_CH0_HCTRL_MODE_U7_V)<<(PCNT_CH0_HCTRL_MODE_U7_S))
+#define PCNT_CH0_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U7_S  20
+
+/* PCNT_CH0_POS_MODE_U7 : R/W ;bitpos:[19:18] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U7  0x00000003
+#define PCNT_CH0_POS_MODE_U7_M  ((PCNT_CH0_POS_MODE_U7_V)<<(PCNT_CH0_POS_MODE_U7_S))
+#define PCNT_CH0_POS_MODE_U7_V  0x3
+#define PCNT_CH0_POS_MODE_U7_S  18
+
+/* PCNT_CH0_NEG_MODE_U7 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * input negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U7  0x00000003
+#define PCNT_CH0_NEG_MODE_U7_M  ((PCNT_CH0_NEG_MODE_U7_V)<<(PCNT_CH0_NEG_MODE_U7_S))
+#define PCNT_CH0_NEG_MODE_U7_V  0x3
+#define PCNT_CH0_NEG_MODE_U7_S  16
+
+/* PCNT_THR_THRES1_EN_U7 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit7's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U7  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_V  0x1
+#define PCNT_THR_THRES1_EN_U7_S  15
+
+/* PCNT_THR_THRES0_EN_U7 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U7  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_V  0x1
+#define PCNT_THR_THRES0_EN_U7_S  14
+
+/* PCNT_THR_L_LIM_EN_U7 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U7  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_V  0x1
+#define PCNT_THR_L_LIM_EN_U7_S  13
+
+/* PCNT_THR_H_LIM_EN_U7 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit7's count
+ * with thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U7  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_V  0x1
+#define PCNT_THR_H_LIM_EN_U7_S  12
+
+/* PCNT_THR_ZERO_EN_U7 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U7  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_V  0x1
+#define PCNT_THR_ZERO_EN_U7_S  11
+
+/* PCNT_FILTER_EN_U7 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit7.
+ */
+
+#define PCNT_FILTER_EN_U7  (BIT(10))
+#define PCNT_FILTER_EN_U7_M  (BIT(10))
+#define PCNT_FILTER_EN_U7_V  0x1
+#define PCNT_FILTER_EN_U7_S  10
+
+/* PCNT_FILTER_THRES_U7 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit7.
+ */
+
+#define PCNT_FILTER_THRES_U7  0x000003FF
+#define PCNT_FILTER_THRES_U7_M  ((PCNT_FILTER_THRES_U7_V)<<(PCNT_FILTER_THRES_U7_S))
+#define PCNT_FILTER_THRES_U7_V  0x3FF
+#define PCNT_FILTER_THRES_U7_S  0
+
+#define PCNT_U7_CONF1_REG          (DR_REG_PCNT_BASE + 0x0058)
+
+/* PCNT_CNT_THRES1_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit7.
+ */
+
+#define PCNT_CNT_THRES1_U7  0x0000FFFF
+#define PCNT_CNT_THRES1_U7_M  ((PCNT_CNT_THRES1_U7_V)<<(PCNT_CNT_THRES1_U7_S))
+#define PCNT_CNT_THRES1_U7_V  0xFFFF
+#define PCNT_CNT_THRES1_U7_S  16
+
+/* PCNT_CNT_THRES0_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit7.
+ */
+
+#define PCNT_CNT_THRES0_U7  0x0000FFFF
+#define PCNT_CNT_THRES0_U7_M  ((PCNT_CNT_THRES0_U7_V)<<(PCNT_CNT_THRES0_U7_S))
+#define PCNT_CNT_THRES0_U7_V  0xFFFF
+#define PCNT_CNT_THRES0_U7_S  0
+
+#define PCNT_U7_CONF2_REG          (DR_REG_PCNT_BASE + 0x005c)
+
+/* PCNT_CNT_L_LIM_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit7.
+ */
+
+#define PCNT_CNT_L_LIM_U7  0x0000FFFF
+#define PCNT_CNT_L_LIM_U7_M  ((PCNT_CNT_L_LIM_U7_V)<<(PCNT_CNT_L_LIM_U7_S))
+#define PCNT_CNT_L_LIM_U7_V  0xFFFF
+#define PCNT_CNT_L_LIM_U7_S  16
+
+/* PCNT_CNT_H_LIM_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit7.
+ */
+
+#define PCNT_CNT_H_LIM_U7  0x0000FFFF
+#define PCNT_CNT_H_LIM_U7_M  ((PCNT_CNT_H_LIM_U7_V)<<(PCNT_CNT_H_LIM_U7_S))
+#define PCNT_CNT_H_LIM_U7_V  0xFFFF
+#define PCNT_CNT_H_LIM_U7_S  0
+
+#define PCNT_U0_CNT_REG          (DR_REG_PCNT_BASE + 0x0060)
+
+/* PCNT_PLUS_CNT_U0 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit0.
+ */
+
+#define PCNT_PLUS_CNT_U0  0x0000FFFF
+#define PCNT_PLUS_CNT_U0_M  ((PCNT_PLUS_CNT_U0_V)<<(PCNT_PLUS_CNT_U0_S))
+#define PCNT_PLUS_CNT_U0_V  0xFFFF
+#define PCNT_PLUS_CNT_U0_S  0
+
+#define PCNT_U1_CNT_REG          (DR_REG_PCNT_BASE + 0x0064)
+
+/* PCNT_PLUS_CNT_U1 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit1.
+ */
+
+#define PCNT_PLUS_CNT_U1  0x0000FFFF
+#define PCNT_PLUS_CNT_U1_M  ((PCNT_PLUS_CNT_U1_V)<<(PCNT_PLUS_CNT_U1_S))
+#define PCNT_PLUS_CNT_U1_V  0xFFFF
+#define PCNT_PLUS_CNT_U1_S  0
+
+#define PCNT_U2_CNT_REG          (DR_REG_PCNT_BASE + 0x0068)
+
+/* PCNT_PLUS_CNT_U2 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit2.
+ */
+
+#define PCNT_PLUS_CNT_U2  0x0000FFFF
+#define PCNT_PLUS_CNT_U2_M  ((PCNT_PLUS_CNT_U2_V)<<(PCNT_PLUS_CNT_U2_S))
+#define PCNT_PLUS_CNT_U2_V  0xFFFF
+#define PCNT_PLUS_CNT_U2_S  0
+
+#define PCNT_U3_CNT_REG          (DR_REG_PCNT_BASE + 0x006c)
+
+/* PCNT_PLUS_CNT_U3 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit3.
+ */
+
+#define PCNT_PLUS_CNT_U3  0x0000FFFF
+#define PCNT_PLUS_CNT_U3_M  ((PCNT_PLUS_CNT_U3_V)<<(PCNT_PLUS_CNT_U3_S))
+#define PCNT_PLUS_CNT_U3_V  0xFFFF
+#define PCNT_PLUS_CNT_U3_S  0
+
+#define PCNT_U4_CNT_REG          (DR_REG_PCNT_BASE + 0x0070)
+
+/* PCNT_PLUS_CNT_U4 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit4.
+ */
+
+#define PCNT_PLUS_CNT_U4  0x0000FFFF
+#define PCNT_PLUS_CNT_U4_M  ((PCNT_PLUS_CNT_U4_V)<<(PCNT_PLUS_CNT_U4_S))
+#define PCNT_PLUS_CNT_U4_V  0xFFFF
+#define PCNT_PLUS_CNT_U4_S  0
+
+#define PCNT_U5_CNT_REG          (DR_REG_PCNT_BASE + 0x0074)
+
+/* PCNT_PLUS_CNT_U5 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit5.
+ */
+
+#define PCNT_PLUS_CNT_U5  0x0000FFFF
+#define PCNT_PLUS_CNT_U5_M  ((PCNT_PLUS_CNT_U5_V)<<(PCNT_PLUS_CNT_U5_S))
+#define PCNT_PLUS_CNT_U5_V  0xFFFF
+#define PCNT_PLUS_CNT_U5_S  0
+
+#define PCNT_U6_CNT_REG          (DR_REG_PCNT_BASE + 0x0078)
+
+/* PCNT_PLUS_CNT_U6 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit6.
+ */
+
+#define PCNT_PLUS_CNT_U6  0x0000FFFF
+#define PCNT_PLUS_CNT_U6_M  ((PCNT_PLUS_CNT_U6_V)<<(PCNT_PLUS_CNT_U6_S))
+#define PCNT_PLUS_CNT_U6_V  0xFFFF
+#define PCNT_PLUS_CNT_U6_S  0
+
+#define PCNT_U7_CNT_REG          (DR_REG_PCNT_BASE + 0x007c)
+
+/* PCNT_PLUS_CNT_U7 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit7.
+ */
+
+#define PCNT_PLUS_CNT_U7  0x0000FFFF
+#define PCNT_PLUS_CNT_U7_M  ((PCNT_PLUS_CNT_U7_V)<<(PCNT_PLUS_CNT_U7_S))
+#define PCNT_PLUS_CNT_U7_V  0xFFFF
+#define PCNT_PLUS_CNT_U7_S  0
+
+#define PCNT_INT_RAW_REG          (DR_REG_PCNT_BASE + 0x0080)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_RAW : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_RAW : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_RAW : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_RAW : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_RAW : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_RAW : RO ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_RAW : RO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_RAW : RO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_S  0
+
+#define PCNT_INT_ST_REG          (DR_REG_PCNT_BASE + 0x0084)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ST : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ST  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ST : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ST  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ST : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ST  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ST  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ST : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ST  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ST : RO; bitpos: [2]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U2_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ST    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_M  (PCNT_CNT_THR_EVENT_U2_INT_ST_V << PCNT_CNT_THR_EVENT_U2_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ST : RO; bitpos: [1]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U1_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ST    (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_M  (PCNT_CNT_THR_EVENT_U1_INT_ST_V << PCNT_CNT_THR_EVENT_U1_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ST : RO; bitpos: [0]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U0_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ST    (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_M  (PCNT_CNT_THR_EVENT_U0_INT_ST_V << PCNT_CNT_THR_EVENT_U0_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_S  0
+
+/* PCNT_INT_ENA_REG register
+ * Interrupt enable register
+ */
+
+#define PCNT_INT_ENA_REG          (DR_REG_PCNT_BASE + 0x0088)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ENA : R/W ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ENA : R/W ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ENA : R/W ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ENA : R/W ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ENA : R/W ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ENA : R/W ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_S  0
+
+#define PCNT_INT_CLR_REG          (DR_REG_PCNT_BASE + 0x008c)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_CLR : WO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel7 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_CLR : WO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel6 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_CLR : WO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel5 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_CLR : WO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel4 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_CLR : WO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel3 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_CLR : WO; bitpos: [2]; default: 0;
+ * Set this bit to clear the PCNT_CNT_THR_EVENT_U2_INT interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_M  (PCNT_CNT_THR_EVENT_U2_INT_CLR_V << PCNT_CNT_THR_EVENT_U2_INT_CLR_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_CLR : WO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel1 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_CLR : WO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel0 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_S  0
+
+#define PCNT_U0_STATUS_REG          (DR_REG_PCNT_BASE + 0x0090)
+
+/* PCNT_CORE_STATUS_U0 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U0  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_M  ((PCNT_CORE_STATUS_U0_V)<<(PCNT_CORE_STATUS_U0_S))
+#define PCNT_CORE_STATUS_U0_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_S  0
+
+/* 0: positive value to zero;
+ * 1: negative value to zero;
+ * 2: counter value negative;
+ * 3: counter value positive
+ */
+
+#define PCNT_STATUS_CNT_MODE    0x3
+#define PCNT_STATUS_CNT_MODE_M  ((PCNT_STATUS_CNT_MODE_V)<<(PCNT_STATUS_CNT_MODE_S))
+#define PCNT_STATUS_CNT_MODE_V  0x3
+#define PCNT_STATUS_CNT_MODE_S  0
+
+/* counter value equals to thresh1 */
+
+#define PCNT_STATUS_THRES1    BIT(2)
+#define PCNT_STATUS_THRES1_M  BIT(2)
+#define PCNT_STATUS_THRES1_V  0x1
+#define PCNT_STATUS_THRES1_S  2
+
+/* counter value equals to thresh0 */
+
+#define PCNT_STATUS_THRES0    BIT(3)
+#define PCNT_STATUS_THRES0_M  BIT(3)
+#define PCNT_STATUS_THRES0_V  0x1
+#define PCNT_STATUS_THRES0_S  3
+
+/* counter value reaches h_lim */
+
+#define PCNT_STATUS_L_LIM    BIT(4)
+#define PCNT_STATUS_L_LIM_M  BIT(4)
+#define PCNT_STATUS_L_LIM_V  0x1
+#define PCNT_STATUS_L_LIM_S  4
+
+/* counter value reaches l_lim */
+
+#define PCNT_STATUS_H_LIM    BIT(5)
+#define PCNT_STATUS_H_LIM_M  BIT(5)
+#define PCNT_STATUS_H_LIM_V  0x1
+#define PCNT_STATUS_H_LIM_S  5
+
+/* counter value equals to zero */
+
+#define PCNT_STATUS_ZERO    BIT(6)
+#define PCNT_STATUS_ZERO_M  BIT(6)
+#define PCNT_STATUS_ZERO_V  0x1
+#define PCNT_STATUS_ZERO_S  6
+
+#define PCNT_U1_STATUS_REG          (DR_REG_PCNT_BASE + 0x0094)
+
+/* PCNT_CORE_STATUS_U1 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U1  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_M  ((PCNT_CORE_STATUS_U1_V)<<(PCNT_CORE_STATUS_U1_S))
+#define PCNT_CORE_STATUS_U1_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_S  0
+
+#define PCNT_U2_STATUS_REG          (DR_REG_PCNT_BASE + 0x0098)
+
+/* PCNT_CORE_STATUS_U2 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U2  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_M  ((PCNT_CORE_STATUS_U2_V)<<(PCNT_CORE_STATUS_U2_S))
+#define PCNT_CORE_STATUS_U2_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_S  0
+
+#define PCNT_U3_STATUS_REG          (DR_REG_PCNT_BASE + 0x009c)
+
+/* PCNT_CORE_STATUS_U3 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U3  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_M  ((PCNT_CORE_STATUS_U3_V)<<(PCNT_CORE_STATUS_U3_S))
+#define PCNT_CORE_STATUS_U3_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_S  0
+
+#define PCNT_U4_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a0)
+/* PCNT_CORE_STATUS_U4 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U4  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_M  ((PCNT_CORE_STATUS_U4_V)<<(PCNT_CORE_STATUS_U4_S))
+#define PCNT_CORE_STATUS_U4_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_S  0
+
+#define PCNT_U5_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a4)
+/* PCNT_CORE_STATUS_U5 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U5  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_M  ((PCNT_CORE_STATUS_U5_V)<<(PCNT_CORE_STATUS_U5_S))
+#define PCNT_CORE_STATUS_U5_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_S  0
+
+#define PCNT_U6_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a8)
+/* PCNT_CORE_STATUS_U6 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U6  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_M  ((PCNT_CORE_STATUS_U6_V)<<(PCNT_CORE_STATUS_U6_S))
+#define PCNT_CORE_STATUS_U6_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_S  0
+
+#define PCNT_U7_STATUS_REG          (DR_REG_PCNT_BASE + 0x00ac)
+
+/* PCNT_CORE_STATUS_U7 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U7  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_M  ((PCNT_CORE_STATUS_U7_V)<<(PCNT_CORE_STATUS_U7_S))
+#define PCNT_CORE_STATUS_U7_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_S  0
+
+#define PCNT_CTRL_REG          (DR_REG_PCNT_BASE + 0x00b0)
+
+/* PCNT_CLK_EN : R/W ;bitpos:[16] ;default: 1'b0 ; */
+
+#define PCNT_CLK_EN  (BIT(16))
+#define PCNT_CLK_EN_M  (BIT(16))
+#define PCNT_CLK_EN_V  0x1
+#define PCNT_CLK_EN_S  16
+
+/* PCNT_CNT_PAUSE_U7 : R/W ;bitpos:[15] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit7's counter. */
+
+#define PCNT_CNT_PAUSE_U7  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_M  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_V  0x1
+#define PCNT_CNT_PAUSE_U7_S  15
+
+/* PCNT_PLUS_CNT_RST_U7 : R/W ;bitpos:[14] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit7's counter. */
+
+#define PCNT_PLUS_CNT_RST_U7  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_M  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_V  0x1
+#define PCNT_PLUS_CNT_RST_U7_S  14
+
+/* PCNT_CNT_PAUSE_U6 : R/W ;bitpos:[13] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit6's counter. */
+
+#define PCNT_CNT_PAUSE_U6  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_M  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_V  0x1
+#define PCNT_CNT_PAUSE_U6_S  13
+
+/* PCNT_PLUS_CNT_RST_U6 : R/W ;bitpos:[12] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit6's counter. */
+
+#define PCNT_PLUS_CNT_RST_U6  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_M  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_V  0x1
+#define PCNT_PLUS_CNT_RST_U6_S  12
+
+/* PCNT_CNT_PAUSE_U5 : R/W ;bitpos:[11] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit5's counter. */
+
+#define PCNT_CNT_PAUSE_U5  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_M  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_V  0x1
+#define PCNT_CNT_PAUSE_U5_S  11
+
+/* PCNT_PLUS_CNT_RST_U5 : R/W ;bitpos:[10] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit5's counter. */
+
+#define PCNT_PLUS_CNT_RST_U5  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_M  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_V  0x1
+#define PCNT_PLUS_CNT_RST_U5_S  10
+
+/* PCNT_CNT_PAUSE_U4 : R/W ;bitpos:[9] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit4's counter. */
+
+#define PCNT_CNT_PAUSE_U4  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_M  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_V  0x1
+#define PCNT_CNT_PAUSE_U4_S  9
+
+/* PCNT_PLUS_CNT_RST_U4 : R/W ;bitpos:[8] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit4's counter. */
+
+#define PCNT_PLUS_CNT_RST_U4  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_M  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_V  0x1
+#define PCNT_PLUS_CNT_RST_U4_S  8
+
+/* PCNT_CNT_PAUSE_U3 : R/W ;bitpos:[7] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit3's counter. */
+
+#define PCNT_CNT_PAUSE_U3  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_M  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_V  0x1
+#define PCNT_CNT_PAUSE_U3_S  7
+
+/* PCNT_PLUS_CNT_RST_U3 : R/W ;bitpos:[6] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit3's counter. */
+
+#define PCNT_PLUS_CNT_RST_U3  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_M  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_V  0x1
+#define PCNT_PLUS_CNT_RST_U3_S  6
+
+/* PCNT_CNT_PAUSE_U2 : R/W ;bitpos:[5] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit2's counter. */
+
+#define PCNT_CNT_PAUSE_U2  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_M  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_V  0x1
+#define PCNT_CNT_PAUSE_U2_S  5
+
+/* PCNT_PLUS_CNT_RST_U2 : R/W ;bitpos:[4] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit2's counter. */
+
+#define PCNT_PLUS_CNT_RST_U2  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_M  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_V  0x1
+#define PCNT_PLUS_CNT_RST_U2_S  4
+
+/* PCNT_CNT_PAUSE_U1 : R/W ;bitpos:[3] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit1's counter. */
+
+#define PCNT_CNT_PAUSE_U1  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_M  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_V  0x1
+#define PCNT_CNT_PAUSE_U1_S  3
+
+/* PCNT_PLUS_CNT_RST_U1 : R/W ;bitpos:[2] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit1's counter. */
+
+#define PCNT_PLUS_CNT_RST_U1  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_M  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_V  0x1
+#define PCNT_PLUS_CNT_RST_U1_S  2
+
+/* PCNT_CNT_PAUSE_U0 : R/W ;bitpos:[1] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit0's counter. */
+
+#define PCNT_CNT_PAUSE_U0  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_M  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_V  0x1
+#define PCNT_CNT_PAUSE_U0_S  1
+
+/* PCNT_PLUS_CNT_RST_U0 : R/W ;bitpos:[0] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit0's counter. */
+
+#define PCNT_PLUS_CNT_RST_U0  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_M  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_V  0x1
+#define PCNT_PLUS_CNT_RST_U0_S  0
+
+#define PCNT_DATE_REG          (DR_REG_PCNT_BASE + 0x00fc)
+
+/* PCNT_DATE : R/W ;bitpos:[31:0] ;default: 32'h14122600 ; */
+
+#define PCNT_DATE    0xFFFFFFFF
+#define PCNT_DATE_M  ((PCNT_DATE_V)<<(PCNT_DATE_S))
+#define PCNT_DATE_V  0xFFFFFFFF
+#define PCNT_DATE_S  0
+
+/* Index macros for CONF0/1/2 */
+
+#define PCNT_CONF0_U(X)   PCNT_U0_CONF0_REG + (X * 12)
+#define PCNT_CONF1_U(X)   PCNT_U0_CONF1_REG + (X * 12)
+#define PCNT_CONF2_U(X)   PCNT_U0_CONF2_REG + (X * 12)
+
+/* Index macros for CONT */
+
+#define PCNT_CNT_U(X)     PCNT_U0_CNT_REG + (X * 4)
+
+/* Index macros for STATUS */
+
+#define PCNT_STATUS_U(X)  PCNT_U0_STATUS_REG + (X * 4)
+
+/* PCNT Reset bit, Even bits: 0, 2, 4, 6 */
+
+#define PCNT_CNT_RST_U(X) (1 << (X * 2))

Review Comment:
   ```suggestion
   #define PCNT_CNT_RST_U(X) (1 << ((X) * 2))
   ```



##########
boards/xtensa/esp32/common/src/esp32_qencoder.c:
##########
@@ -0,0 +1,65 @@
+/****************************************************************************
+ * boards/xtensa/esp32/common/src/esp32_qencoder.c
+ *
+ * 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 <errno.h>
+#include <debug.h>
+#include <stdio.h>
+
+#include <nuttx/sensors/qencoder.h>
+#include <arch/board/board.h>
+
+#include "esp32_qencoder.h"
+#include "chip.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_qencoder_initialize
+ *
+ * Description:
+ *   Initialize the quadrature encoder driver for the given timer
+ *
+ ****************************************************************************/
+
+int board_qencoder_initialize(int devno, int pcntno)
+{
+  int ret;
+  char devpath[12];
+
+  /* Initialize a quadrature encoder interface. */
+
+  sninfo("Initializing the quadrature encoder using PCNT%d\n", pcntno);
+  snprintf(devpath, 12, "/dev/qe%d", devno);

Review Comment:
   ```suggestion
     snprintf(devpath, sizeof(devpath), "/dev/qe%d", devno);
   ```



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {1,2,3,4,5,6,7,8} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,

Review Comment:
   Description in struct is `uint8_t   pcntid;        /* PCNT ID {1,2,3,4,5,6,7,8} */`, so this assignment is confusing



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#endif

Review Comment:
   ```suggestion
   #  ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
   #    warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
   #  endif
   ```
   same for other similar places



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {1,2,3,4,5,6,7,8} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t) (getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + (int32_t) count;

Review Comment:
   ```suggestion
     *pos = position + count;
   ```
   not needed singe `position` is `int32_t` and `count` will be promoted automatically.



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {1,2,3,4,5,6,7,8} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t) (getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);

Review Comment:
   ```suggestion
     count = (int16_t)(getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
   ```



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {1,2,3,4,5,6,7,8} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t) (getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + (int32_t) count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", pcnt);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse)
+    {
+      snerr("ERROR: PCNT%d is in-use\n", pcnt);
+      return -EBUSY;
+    }
+
+  /* Register the upper-half driver */
+
+  ret = qe_register(devpath, (struct qe_lowerhalf_s *)priv);

Review Comment:
   Optional
   ```suggestion
     ret = qe_register(devpath, &priv->ops);
   ```



##########
arch/xtensa/src/esp32/esp32_qencoder.c:
##########
@@ -0,0 +1,928 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_qencoder.c
+ *
+ * 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 <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+#include <inttypes.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/sensors/qencoder.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "esp32_gpio.h"
+#include "esp32_irq.h"
+
+#include "xtensa.h"
+#include "hardware/esp32_soc.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_pinmap.h"
+#include "hardware/esp32_gpio_sigmap.h"
+#include "hardware/esp32_pcnt.h"
+#include "esp32_qencoder.h"
+
+#ifdef CONFIG_SENSORS_QENCODER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Input filter *************************************************************/
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+#ifndef CONFIG_ESP32_PCNT_U0_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U0"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+#ifndef CONFIG_ESP32_PCNT_U1_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U1"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+#ifndef CONFIG_ESP32_PCNT_U2_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U2"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+#ifndef CONFIG_ESP32_PCNT_U3_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U3"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+#ifndef CONFIG_ESP32_PCNT_U4_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U4"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+#ifndef CONFIG_ESP32_PCNT_U5_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U5"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+#ifndef CONFIG_ESP32_PCNT_U6_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U6"
+#endif
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+#ifndef CONFIG_ESP32_PCNT_U7_FILTER_EN
+#  warning "Glitch Filter is recommended for Quadrature Encoder on PCNT_U7"
+#endif
+#endif
+
+/* Debug ********************************************************************/
+
+/* Non-standard debug that may be enabled just for testing the quadrature
+ * encoder
+ */
+
+#ifndef CONFIG_DEBUG_FEATURES
+#  undef CONFIG_DEBUG_SENSORS
+#endif
+
+#ifdef CONFIG_DEBUG_SENSORS
+#  ifdef CONFIG_DEBUG_INFO
+#    define qe_dumpgpio(p,m)    esp32_dumpgpio(p,m)
+#  else
+#    define qe_dumpgpio(p,m)
+#  endif
+#else
+#  define qe_dumpgpio(p,m)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Constant configuration structure that is retained in FLASH */
+
+struct esp32_qeconfig_s
+{
+  uint8_t   pcntid;        /* PCNT ID {1,2,3,4,5,6,7,8} */
+  uint8_t   ch0_gpio;      /* Channel 0 gpio pin (Edge/Pulse) */
+  uint8_t   ch1_gpio;      /* Channel 1 gpio pin (Level/Ctrl) */
+  uint32_t  ch0_pulse_sig; /* ch0 pulse signal index */
+  uint32_t  ch0_ctrl_sig;  /* ch0 ctrl signal index */
+  uint32_t  ch1_pulse_sig; /* ch1 pulse signal index */
+  uint32_t  ch1_ctrl_sig;  /* ch1 ctrl signal index */
+  uint16_t  filter_thres;  /* Filter threshold for this PCNT Unit */
+};
+
+/* NOTE: we are using Quadrature Encoder in X4 mode on ESP32 PCNT, then
+ * instead of using 'pulse_gpio' and 'ctrl_gpio' names, we only use ch0_gpio
+ * and ch1_gpio names. It avoid confusion, since the same signal that is used
+ * on pin 'pulse' of CH0 is also connected to 'ctrl' pin of the CH1 and
+ * 'ctrl' pin of CH0 is also connected on 'pulse' pin of CH1.
+ */
+
+/* Overall, RAM-based state structure */
+
+struct esp32_lowerhalf_s
+{
+  /* The first field of this state structure must be a pointer to the
+   * lower-half callback structure:
+   */
+
+  const struct qe_ops_s *ops; /* Lower half callback structure */
+
+  /* ESP32 driver-specific fields: */
+
+  const struct esp32_qeconfig_s *config; /* static configuration */
+
+  bool inuse; /* True: The lower-half driver is in-use */
+
+  volatile int32_t position; /* The current position offset */
+
+  spinlock_t lock; /* Device specific lock. */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Helper functions */
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg);
+#else
+#  define esp32_dumpregs(priv,msg)
+#endif
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt);
+
+/* Interrupt handling */
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg);
+#endif
+
+/* Lower-half Quadrature Encoder Driver Methods */
+
+static int esp32_setup(struct qe_lowerhalf_s *lower);
+static int esp32_shutdown(struct qe_lowerhalf_s *lower);
+static int esp32_position(struct qe_lowerhalf_s *lower,
+                          int32_t *pos);
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_reset(struct qe_lowerhalf_s *lower);
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos);
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The lower half callback structure */
+
+static const struct qe_ops_s g_qecallbacks =
+{
+  .setup     = esp32_setup,
+  .shutdown  = esp32_shutdown,
+  .position  = esp32_position,
+  .setposmax = esp32_setposmax,
+  .reset     = esp32_reset,
+  .setindex  = esp32_setindex,
+  .ioctl     = esp32_ioctl,
+};
+
+/* Per-pcnt state structures */
+
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+static const struct esp32_qeconfig_s g_pcnt0config =
+{
+  .pcntid        = 0,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U0_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U0_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN0_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN0_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN0_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN0_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U0_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt0lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt0config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+static const struct esp32_qeconfig_s g_pcnt1config =
+{
+  .pcntid        = 1,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U1_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U1_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN1_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN1_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN1_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN1_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U1_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt1lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt1config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+static const struct esp32_qeconfig_s g_pcnt2config =
+{
+  .pcntid       = 2,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U2_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U2_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN2_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN2_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN2_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN2_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U2_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt2lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt2config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+static const struct esp32_qeconfig_s g_pcnt3config =
+{
+  .pcntid        = 3,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U3_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U3_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN3_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN3_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN3_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN3_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U3_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt3lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt3config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+static const struct esp32_qeconfig_s g_pcnt4config =
+{
+  .pcntid        = 4,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U4_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U4_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN4_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN4_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN4_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN4_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U4_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt4lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt4config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+static const struct esp32_qeconfig_s g_pcnt5config =
+{
+  .pcntid       = 5,
+  .ch0_gpio     = CONFIG_ESP32_PCNT_U5_CH0_EDGE_PIN,
+  .ch1_gpio     = CONFIG_ESP32_PCNT_U5_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN5_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN5_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN5_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN5_IDX,
+  .filter_thres = CONFIG_ESP32_PCNT_U5_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt5lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt5config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+static const struct esp32_qeconfig_s g_pcnt6config =
+{
+  .pcntid        = 6,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U6_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U6_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN6_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN6_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN6_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN6_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U6_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt6lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt6config,
+  .inuse    = false,
+};
+#endif
+
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+static const struct esp32_qeconfig_s g_pcnt7config =
+{
+  .pcntid        = 7,
+  .ch0_gpio      = CONFIG_ESP32_PCNT_U7_CH0_EDGE_PIN,
+  .ch1_gpio      = CONFIG_ESP32_PCNT_U7_CH1_LEVEL_PIN,
+  .ch0_pulse_sig = PCNT_SIG_CH0_IN7_IDX,
+  .ch1_pulse_sig = PCNT_SIG_CH1_IN7_IDX,
+  .ch0_ctrl_sig  = PCNT_CTRL_CH0_IN7_IDX,
+  .ch1_ctrl_sig  = PCNT_CTRL_CH1_IN7_IDX,
+  .filter_thres  = CONFIG_ESP32_PCNT_U7_FILTER_THRES,
+};
+
+static struct esp32_lowerhalf_s g_pcnt7lower =
+{
+  .ops      = &g_qecallbacks,
+  .config   = &g_pcnt7config,
+  .inuse    = false,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_dumpregs
+ *
+ * Description:
+ *   Dump all timer registers.
+ *
+ * Input Parameters:
+ *   priv - A reference to the QENCODER block status
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_SENSORS) && defined(CONFIG_DEBUG_INFO)
+static void esp32_dumpregs(struct esp32_lowerhalf_s *priv,
+                           const char *msg)
+{
+  sninfo("%s:\n", msg);
+  sninfo("  PCNT_U0_CONF0_REG: %08x PCNT_U1_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(0)),
+         getreg32(PCNT_CONF0_U(1)));
+  sninfo("  PCNT_U2_CONF0_REG: %08x PCNT_U3_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(2)),
+         getreg32(PCNT_CONF0_U(3)));
+  sninfo("  PCNT_U4_CONF0_REG: %08x PCNT_U5_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(4)),
+         getreg32(PCNT_CONF0_U(5)));
+  sninfo("  PCNT_U6_CONF0_REG: %08x PCNT_U7_CONF0_REG:  %08x\n",
+         getreg32(PCNT_CONF0_U(6)),
+         getreg32(PCNT_CONF0_U(7)));
+  sninfo("  PCNT_U0_CONF1_REG: %08x PCNT_U1_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(0)),
+         getreg32(PCNT_CONF1_U(1)));
+  sninfo("  PCNT_U2_CONF1_REG: %08x PCNT_U3_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(2)),
+         getreg32(PCNT_CONF1_U(3)));
+  sninfo("  PCNT_U4_CONF1_REG: %08x PCNT_U5_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(4)),
+         getreg32(PCNT_CONF1_U(5)));
+  sninfo("  PCNT_U6_CONF1_REG: %08x PCNT_U7_CONF1_REG:  %08x\n",
+         getreg32(PCNT_CONF1_U(6)),
+         getreg32(PCNT_CONF1_U(7)));
+  sninfo("  PCNT_U0_CONF2_REG: %08x PCNT_U1_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(0)),
+         getreg32(PCNT_CONF2_U(1)));
+  sninfo("  PCNT_U2_CONF2_REG: %08x PCNT_U3_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(2)),
+         getreg32(PCNT_CONF2_U(3)));
+  sninfo("  PCNT_U4_CONF2_REG: %08x PCNT_U5_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(4)),
+         getreg32(PCNT_CONF2_U(5)));
+  sninfo("  PCNT_U6_CONF2_REG: %08x PCNT_U7_CONF2_REG:  %08x\n",
+         getreg32(PCNT_CONF2_U(6)),
+         getreg32(PCNT_CONF2_U(7)));
+  sninfo("  PCNT_U0_CNT_REG: %08x PCNT_U1_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(0)),
+         getreg32(PCNT_CNT_U(1)));
+  sninfo("  PCNT_U2_CNT_REG: %08x PCNT_U3_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(2)),
+         getreg32(PCNT_CNT_U(3)));
+  sninfo("  PCNT_U4_CNT_REG: %08x PCNT_U5_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(4)),
+         getreg32(PCNT_CNT_U(5)));
+  sninfo("  PCNT_U6_CNT_REG: %08x PCNT_U7_CNT_REG:  %08x\n",
+         getreg32(PCNT_CNT_U(6)),
+         getreg32(PCNT_CNT_U(7)));
+  sninfo("  PCNT_CTRL_REF: %08x\n",
+         getreg32(PCNT_CTRL_REG);
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_pcnt2lower
+ *
+ * Description:
+ *   Map a PCNT number to a device structure
+ *
+ ****************************************************************************/
+
+static struct esp32_lowerhalf_s *esp32_pcnt2lower(int pcnt)
+{
+  switch (pcnt)
+    {
+#ifdef CONFIG_ESP32_PCNT_U0_QE
+    case 0:
+      return &g_pcnt0lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U1_QE
+    case 1:
+      return &g_pcnt1lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U2_QE
+    case 2:
+      return &g_pcnt2lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U3_QE
+    case 3:
+      return &g_pcnt3lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U4_QE
+    case 4:
+      return &g_pcnt4lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U5_QE
+    case 5:
+      return &g_pcnt5lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U6_QE
+    case 6:
+      return &g_pcnt6lower;
+#endif
+#ifdef CONFIG_ESP32_PCNT_U7_QE
+    case 7:
+      return &g_pcnt7lower;
+#endif
+    default:
+      return NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_interrupt
+ *
+ * Description:
+ *   Common timer interrupt handling.  NOTE: Only 16-bit timers require timer
+ *   interrupts.
+ *
+ ****************************************************************************/
+
+#if 0 /* FIXME: To be implement */
+static int esp32_interrupt(int irq, void *context, void *arg)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)arg;
+  uint16_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: esp32_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.
+ *   The initial position value should be zero. *
+ *
+ ****************************************************************************/
+
+static int esp32_setup(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  /* Protected access to the registers */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  esp32_dumpregs(priv, "Before setup");
+
+  /* Enable the PCNT Clock and Reset the peripheral */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, 0, DPORT_PCNT_CLK_EN);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, 0, DPORT_PCNT_RST);
+  modifyreg32(DPORT_PERIP_RST_EN_REG, DPORT_PCNT_RST, 0);
+
+  /* Disable all events */
+
+  putreg32(0, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure the limits range PCNT_CNT_L_LIM | PCNT_CNT_H_LIM */
+
+  regval  = INT16_MIN << 16;
+  regval |= INT16_MAX;
+  putreg32(regval, PCNT_CONF2_U(priv->config->pcntid));
+
+  /* Setup POS/NEG/LCTRL/HCTRL/FILTER modes */
+
+  regval  = priv->config->filter_thres;
+  regval |= PCNT_COUNT_INC << PCNT_CH0_NEG_MODE_U0_S;      /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_DEC << PCNT_CH0_POS_MODE_U0_S;      /* Increase on Rising-Edge */
+  regval |= PCNT_MODE_REVERSE << PCNT_CH0_LCTRL_MODE_U0_S; /* Rising A with B in HIGH = CW step */
+  regval |= PCNT_MODE_KEEP << PCNT_CH0_HCTRL_MODE_U0_S;    /* Rising A with B in LOW = CCW step */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  regval |= PCNT_COUNT_DEC << PCNT_CH1_NEG_MODE_U0_S; /* Ignore Falling-Edge */
+  regval |= PCNT_COUNT_INC << PCNT_CH1_POS_MODE_U0_S; /* Increase on Rising-Edge */
+
+  putreg32(regval, PCNT_CONF0_U(priv->config->pcntid));
+
+  /* Configure GPIO pins as Input with Pull-Up enabled */
+
+  esp32_configgpio(priv->config->ch0_gpio, INPUT_FUNCTION_3 | PULLUP);
+  esp32_configgpio(priv->config->ch1_gpio, INPUT_FUNCTION_3 | PULLUP);
+
+  /* Connect Channel A (ch0_gpio) and Channel B (ch1_gpio) crossed for X4 */
+
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch0_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch0_ctrl_sig, 0);
+
+  esp32_gpio_matrix_in(priv->config->ch1_gpio,
+                       priv->config->ch1_pulse_sig, 0);
+  esp32_gpio_matrix_in(priv->config->ch0_gpio,
+                       priv->config->ch1_ctrl_sig, 0);
+
+  /* Clear the Reset bit to nable the Pulse Counter */
+
+  regval = getreg32(PCNT_CTRL_REG);
+  regval &= ~(1 << (2 * priv->config->pcntid));
+  putreg32(regval, PCNT_CTRL_REG);
+
+  esp32_dumpregs(priv, "After setup");
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_shutdown
+ *
+ * Description:
+ *   This method is called when the driver is closed.  The lower half driver
+ *   should stop data collection, free any resources, disable timer hardware,
+ *   and put the system into the lowest possible power usage state
+ *
+ ****************************************************************************/
+
+static int esp32_shutdown(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+  /* Disable PCNT clock */
+
+  modifyreg32(DPORT_PERIP_CLK_EN_REG, DPORT_PCNT_CLK_EN, 0);
+
+  /* Make sure initial position is 0 */
+
+  priv->position = 0;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_position
+ *
+ * Description:
+ *   Return the current position measurement.
+ *
+ ****************************************************************************/
+
+static int esp32_position(struct qe_lowerhalf_s *lower, int32_t *pos)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  int32_t position;
+  int16_t count;
+
+  DEBUGASSERT(lower && priv->inuse);
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  position = priv->position;
+  count = (int16_t) (getreg32(PCNT_CNT_U(priv->config->pcntid)) & 0xffff);
+
+  /* Return the position measurement */
+
+  *pos = position + (int32_t) count;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setposmax
+ *
+ * Description:
+ *   Set the maximum encoder position.
+ *
+ ****************************************************************************/
+
+static int esp32_setposmax(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_DISABLE_EXTEND16BTIMERS
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+
+#if defined(HAVE_MIXEDWIDTH_TIMERS)
+  if (priv->config->width == 32)
+    {
+      esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+  else
+    {
+      esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+    }
+#elif defined(HAVE_32BIT_TIMERS)
+  esp32_putreg32(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#else
+  esp32_putreg16(priv, ESP32_GTIM_ARR_OFFSET, pos);
+#endif
+
+  return OK;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_reset
+ *
+ * Description:
+ *   Reset the position measurement to zero.
+ *
+ ****************************************************************************/
+
+static int esp32_reset(struct qe_lowerhalf_s *lower)
+{
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  irqstate_t flags;
+  uint32_t regval;
+
+  sninfo("Resetting position to zero\n");
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Reset this Pulse Counter Unit. */
+
+  flags = spin_lock_irqsave(&priv->lock);
+
+  regval  = getreg32(PCNT_CTRL_REG);
+  regval |= PCNT_CNT_RST_U(priv->config->pcntid);
+  putreg32(regval, PCNT_CTRL_REG);
+
+  priv->position = 0;
+
+  spin_unlock_irqrestore(&priv->lock, flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_setindex
+ *
+ * Description:
+ *   Set the index pin position
+ *
+ ****************************************************************************/
+
+static int esp32_setindex(struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_ESP32_QENCODER_INDEX_PIN
+  struct esp32_lowerhalf_s *priv = (struct esp32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE PCNT%d the index pin positon %" PRIx32 "\n",
+         priv->config->pcntid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE PCNT%d index not registered\n",
+            priv->config->pcntid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+  priv->index_offset = pos;
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp32_ioctl
+ *
+ * Description:
+ *   Lower-half logic may support platform-specific ioctl commands
+ *
+ ****************************************************************************/
+
+static int esp32_ioctl(struct qe_lowerhalf_s *lower, int cmd,
+                       unsigned long arg)
+{
+  /* No ioctl commands supported */
+
+  /* TODO add an IOCTL to control the encoder pulse count prescaler */
+
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_qeinitialize
+ *
+ * Description:
+ *   Initialize a quadrature encoder interface.  This function must be
+ *   called from board-specific logic.
+ *
+ * Input Parameters:
+ *   devpath - The full path to the driver to register. E.g., "/dev/qe0"
+ *   pcnt    - The PCNT number to used.  'pcnt' must be an element of
+ *             {0,1,2,3,4,5,6,7,8}
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int esp32_qeinitialize(const char *devpath, int pcnt)
+{
+  struct esp32_lowerhalf_s *priv;
+  int ret;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = esp32_pcnt2lower(pcnt);
+  if (!priv)
+    {
+      snerr("ERROR: PCNT%d support not configured\n", pcnt);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse)
+    {
+      snerr("ERROR: PCNT%d is in-use\n", pcnt);
+      return -EBUSY;
+    }
+
+  /* Register the upper-half driver */
+
+  ret = qe_register(devpath, (struct qe_lowerhalf_s *)priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: qe_register failed: %d\n", ret);
+      return ret;
+    }
+
+  /* Make sure that the PCNT is in the shutdown state */
+
+  esp32_shutdown((struct qe_lowerhalf_s *)priv);

Review Comment:
   Optional
   ```suggestion
     esp32_shutdown(&priv->ops);
   ```



##########
arch/xtensa/src/esp32/hardware/esp32_pcnt.h:
##########
@@ -0,0 +1,2495 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/hardware/esp32_pcnt.h
+ *
+ * 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_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+#define __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* PCNT_U0_CONF0_REG register
+ * Configuration register 0 for unit 0
+ */
+
+#define PCNT_U0_CONF0_REG (DR_REG_PCNT_BASE + 0x0)
+
+/* PCNT_CH1_LCTRL_MODE_U0 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_M  (PCNT_CH1_LCTRL_MODE_U0_V << PCNT_CH1_LCTRL_MODE_U0_S)
+#define PCNT_CH1_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U0 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_M  (PCNT_CH1_HCTRL_MODE_U0_V << PCNT_CH1_HCTRL_MODE_U0_S)
+#define PCNT_CH1_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_S  28
+
+/* PCNT_CH1_POS_MODE_U0 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U0    0x00000003
+#define PCNT_CH1_POS_MODE_U0_M  (PCNT_CH1_POS_MODE_U0_V << PCNT_CH1_POS_MODE_U0_S)
+#define PCNT_CH1_POS_MODE_U0_V  0x00000003
+#define PCNT_CH1_POS_MODE_U0_S  26
+
+/* PCNT_CH1_NEG_MODE_U0 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U0    0x00000003
+#define PCNT_CH1_NEG_MODE_U0_M  (PCNT_CH1_NEG_MODE_U0_V << PCNT_CH1_NEG_MODE_U0_S)
+#define PCNT_CH1_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U0_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U0 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_M  (PCNT_CH0_LCTRL_MODE_U0_V << PCNT_CH0_LCTRL_MODE_U0_S)
+#define PCNT_CH0_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U0 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_M  (PCNT_CH0_HCTRL_MODE_U0_V << PCNT_CH0_HCTRL_MODE_U0_S)
+#define PCNT_CH0_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_S  20
+
+/* PCNT_CH0_POS_MODE_U0 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U0    0x00000003
+#define PCNT_CH0_POS_MODE_U0_M  (PCNT_CH0_POS_MODE_U0_V << PCNT_CH0_POS_MODE_U0_S)
+#define PCNT_CH0_POS_MODE_U0_V  0x00000003
+#define PCNT_CH0_POS_MODE_U0_S  18
+
+/* PCNT_CH0_NEG_MODE_U0 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U0    0x00000003
+#define PCNT_CH0_NEG_MODE_U0_M  (PCNT_CH0_NEG_MODE_U0_V << PCNT_CH0_NEG_MODE_U0_S)
+#define PCNT_CH0_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U0_S  16
+
+/* PCNT_THR_THRES1_EN_U0 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 0's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U0    (BIT(15))
+#define PCNT_THR_THRES1_EN_U0_M  (PCNT_THR_THRES1_EN_U0_V << PCNT_THR_THRES1_EN_U0_S)
+#define PCNT_THR_THRES1_EN_U0_V  0x00000001
+#define PCNT_THR_THRES1_EN_U0_S  15
+
+/* PCNT_THR_THRES0_EN_U0 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 0's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U0    (BIT(14))
+#define PCNT_THR_THRES0_EN_U0_M  (PCNT_THR_THRES0_EN_U0_V << PCNT_THR_THRES0_EN_U0_S)
+#define PCNT_THR_THRES0_EN_U0_V  0x00000001
+#define PCNT_THR_THRES0_EN_U0_S  14
+
+/* PCNT_THR_L_LIM_EN_U0 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 0's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U0    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U0_M  (PCNT_THR_L_LIM_EN_U0_V << PCNT_THR_L_LIM_EN_U0_S)
+#define PCNT_THR_L_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U0_S  13
+
+/* PCNT_THR_H_LIM_EN_U0 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 0's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U0    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U0_M  (PCNT_THR_H_LIM_EN_U0_V << PCNT_THR_H_LIM_EN_U0_S)
+#define PCNT_THR_H_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U0_S  12
+
+/* PCNT_THR_ZERO_EN_U0 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 0's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U0    (BIT(11))
+#define PCNT_THR_ZERO_EN_U0_M  (PCNT_THR_ZERO_EN_U0_V << PCNT_THR_ZERO_EN_U0_S)
+#define PCNT_THR_ZERO_EN_U0_V  0x00000001
+#define PCNT_THR_ZERO_EN_U0_S  11
+
+/* PCNT_FILTER_EN_U0 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 0's input filter.
+ */
+
+#define PCNT_FILTER_EN_U0    (BIT(10))
+#define PCNT_FILTER_EN_U0_M  (PCNT_FILTER_EN_U0_V << PCNT_FILTER_EN_U0_S)
+#define PCNT_FILTER_EN_U0_V  0x00000001
+#define PCNT_FILTER_EN_U0_S  10
+
+/* PCNT_FILTER_THRES_U0 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U0    0x000003ff
+#define PCNT_FILTER_THRES_U0_M  (PCNT_FILTER_THRES_U0_V << PCNT_FILTER_THRES_U0_S)
+#define PCNT_FILTER_THRES_U0_V  0x000003ff
+#define PCNT_FILTER_THRES_U0_S  0
+
+/* PCNT_U0_CONF1_REG register
+ * Configuration register 1 for unit 0
+ */
+
+#define PCNT_U0_CONF1_REG (DR_REG_PCNT_BASE + 0x4)
+
+/* PCNT_CNT_THRES1_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES1_U0    0x0000ffff
+#define PCNT_CNT_THRES1_U0_M  (PCNT_CNT_THRES1_U0_V << PCNT_CNT_THRES1_U0_S)
+#define PCNT_CNT_THRES1_U0_V  0x0000ffff
+#define PCNT_CNT_THRES1_U0_S  16
+
+/* PCNT_CNT_THRES0_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES0_U0    0x0000ffff
+#define PCNT_CNT_THRES0_U0_M  (PCNT_CNT_THRES0_U0_V << PCNT_CNT_THRES0_U0_S)
+#define PCNT_CNT_THRES0_U0_V  0x0000ffff
+#define PCNT_CNT_THRES0_U0_S  0
+
+/* PCNT_U0_CONF2_REG register
+ * Configuration register 2 for unit 0
+ */
+
+#define PCNT_U0_CONF2_REG (DR_REG_PCNT_BASE + 0x8)
+
+/* PCNT_CNT_L_LIM_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 0.
+ */
+
+#define PCNT_CNT_L_LIM_U0    0x0000ffff
+#define PCNT_CNT_L_LIM_U0_M  (PCNT_CNT_L_LIM_U0_V << PCNT_CNT_L_LIM_U0_S)
+#define PCNT_CNT_L_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U0_S  16
+
+/* PCNT_CNT_H_LIM_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 0.
+ */
+
+#define PCNT_CNT_H_LIM_U0    0x0000ffff
+#define PCNT_CNT_H_LIM_U0_M  (PCNT_CNT_H_LIM_U0_V << PCNT_CNT_H_LIM_U0_S)
+#define PCNT_CNT_H_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U0_S  0
+
+/* PCNT_U1_CONF0_REG register
+ * Configuration register 0 for unit 1
+ */
+
+#define PCNT_U1_CONF0_REG (DR_REG_PCNT_BASE + 0xc)
+
+/* PCNT_CH1_LCTRL_MODE_U1 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_M  (PCNT_CH1_LCTRL_MODE_U1_V << PCNT_CH1_LCTRL_MODE_U1_S)
+#define PCNT_CH1_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U1 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_M  (PCNT_CH1_HCTRL_MODE_U1_V << PCNT_CH1_HCTRL_MODE_U1_S)
+#define PCNT_CH1_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_S  28
+
+/* PCNT_CH1_POS_MODE_U1 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U1    0x00000003
+#define PCNT_CH1_POS_MODE_U1_M  (PCNT_CH1_POS_MODE_U1_V << PCNT_CH1_POS_MODE_U1_S)
+#define PCNT_CH1_POS_MODE_U1_V  0x00000003
+#define PCNT_CH1_POS_MODE_U1_S  26
+
+/* PCNT_CH1_NEG_MODE_U1 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U1    0x00000003
+#define PCNT_CH1_NEG_MODE_U1_M  (PCNT_CH1_NEG_MODE_U1_V << PCNT_CH1_NEG_MODE_U1_S)
+#define PCNT_CH1_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U1_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U1 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_M  (PCNT_CH0_LCTRL_MODE_U1_V << PCNT_CH0_LCTRL_MODE_U1_S)
+#define PCNT_CH0_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U1 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_M  (PCNT_CH0_HCTRL_MODE_U1_V << PCNT_CH0_HCTRL_MODE_U1_S)
+#define PCNT_CH0_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_S  20
+
+/* PCNT_CH0_POS_MODE_U1 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U1    0x00000003
+#define PCNT_CH0_POS_MODE_U1_M  (PCNT_CH0_POS_MODE_U1_V << PCNT_CH0_POS_MODE_U1_S)
+#define PCNT_CH0_POS_MODE_U1_V  0x00000003
+#define PCNT_CH0_POS_MODE_U1_S  18
+
+/* PCNT_CH0_NEG_MODE_U1 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U1    0x00000003
+#define PCNT_CH0_NEG_MODE_U1_M  (PCNT_CH0_NEG_MODE_U1_V << PCNT_CH0_NEG_MODE_U1_S)
+#define PCNT_CH0_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U1_S  16
+
+/* PCNT_THR_THRES1_EN_U1 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 1's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U1    (BIT(15))
+#define PCNT_THR_THRES1_EN_U1_M  (PCNT_THR_THRES1_EN_U1_V << PCNT_THR_THRES1_EN_U1_S)
+#define PCNT_THR_THRES1_EN_U1_V  0x00000001
+#define PCNT_THR_THRES1_EN_U1_S  15
+
+/* PCNT_THR_THRES0_EN_U1 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 1's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U1    (BIT(14))
+#define PCNT_THR_THRES0_EN_U1_M  (PCNT_THR_THRES0_EN_U1_V << PCNT_THR_THRES0_EN_U1_S)
+#define PCNT_THR_THRES0_EN_U1_V  0x00000001
+#define PCNT_THR_THRES0_EN_U1_S  14
+
+/* PCNT_THR_L_LIM_EN_U1 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 1's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U1    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U1_M  (PCNT_THR_L_LIM_EN_U1_V << PCNT_THR_L_LIM_EN_U1_S)
+#define PCNT_THR_L_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U1_S  13
+
+/* PCNT_THR_H_LIM_EN_U1 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 1's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U1    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U1_M  (PCNT_THR_H_LIM_EN_U1_V << PCNT_THR_H_LIM_EN_U1_S)
+#define PCNT_THR_H_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U1_S  12
+
+/* PCNT_THR_ZERO_EN_U1 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 1's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U1    (BIT(11))
+#define PCNT_THR_ZERO_EN_U1_M  (PCNT_THR_ZERO_EN_U1_V << PCNT_THR_ZERO_EN_U1_S)
+#define PCNT_THR_ZERO_EN_U1_V  0x00000001
+#define PCNT_THR_ZERO_EN_U1_S  11
+
+/* PCNT_FILTER_EN_U1 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 1's input filter.
+ */
+
+#define PCNT_FILTER_EN_U1    (BIT(10))
+#define PCNT_FILTER_EN_U1_M  (PCNT_FILTER_EN_U1_V << PCNT_FILTER_EN_U1_S)
+#define PCNT_FILTER_EN_U1_V  0x00000001
+#define PCNT_FILTER_EN_U1_S  10
+
+/* PCNT_FILTER_THRES_U1 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U1    0x000003ff
+#define PCNT_FILTER_THRES_U1_M  (PCNT_FILTER_THRES_U1_V << PCNT_FILTER_THRES_U1_S)
+#define PCNT_FILTER_THRES_U1_V  0x000003ff
+#define PCNT_FILTER_THRES_U1_S  0
+
+/* PCNT_U1_CONF1_REG register
+ * Configuration register 1 for unit 1
+ */
+
+#define PCNT_U1_CONF1_REG (DR_REG_PCNT_BASE + 0x10)
+
+/* PCNT_CNT_THRES1_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES1_U1    0x0000ffff
+#define PCNT_CNT_THRES1_U1_M  (PCNT_CNT_THRES1_U1_V << PCNT_CNT_THRES1_U1_S)
+#define PCNT_CNT_THRES1_U1_V  0x0000ffff
+#define PCNT_CNT_THRES1_U1_S  16
+
+/* PCNT_CNT_THRES0_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES0_U1    0x0000ffff
+#define PCNT_CNT_THRES0_U1_M  (PCNT_CNT_THRES0_U1_V << PCNT_CNT_THRES0_U1_S)
+#define PCNT_CNT_THRES0_U1_V  0x0000ffff
+#define PCNT_CNT_THRES0_U1_S  0
+
+/* PCNT_U1_CONF2_REG register
+ * Configuration register 2 for unit 1
+ */
+
+#define PCNT_U1_CONF2_REG (DR_REG_PCNT_BASE + 0x14)
+
+/* PCNT_CNT_L_LIM_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 1.
+ */
+
+#define PCNT_CNT_L_LIM_U1    0x0000ffff
+#define PCNT_CNT_L_LIM_U1_M  (PCNT_CNT_L_LIM_U1_V << PCNT_CNT_L_LIM_U1_S)
+#define PCNT_CNT_L_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U1_S  16
+
+/* PCNT_CNT_H_LIM_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 1.
+ */
+
+#define PCNT_CNT_H_LIM_U1    0x0000ffff
+#define PCNT_CNT_H_LIM_U1_M  (PCNT_CNT_H_LIM_U1_V << PCNT_CNT_H_LIM_U1_S)
+#define PCNT_CNT_H_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U1_S  0
+
+/* PCNT_U2_CONF0_REG register
+ * Configuration register 0 for unit 2
+ */
+
+#define PCNT_U2_CONF0_REG (DR_REG_PCNT_BASE + 0x18)
+
+/* PCNT_CH1_LCTRL_MODE_U2 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_M  (PCNT_CH1_LCTRL_MODE_U2_V << PCNT_CH1_LCTRL_MODE_U2_S)
+#define PCNT_CH1_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U2 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_M  (PCNT_CH1_HCTRL_MODE_U2_V << PCNT_CH1_HCTRL_MODE_U2_S)
+#define PCNT_CH1_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_S  28
+
+/* PCNT_CH1_POS_MODE_U2 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U2    0x00000003
+#define PCNT_CH1_POS_MODE_U2_M  (PCNT_CH1_POS_MODE_U2_V << PCNT_CH1_POS_MODE_U2_S)
+#define PCNT_CH1_POS_MODE_U2_V  0x00000003
+#define PCNT_CH1_POS_MODE_U2_S  26
+
+/* PCNT_CH1_NEG_MODE_U2 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U2    0x00000003
+#define PCNT_CH1_NEG_MODE_U2_M  (PCNT_CH1_NEG_MODE_U2_V << PCNT_CH1_NEG_MODE_U2_S)
+#define PCNT_CH1_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U2_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U2 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_M  (PCNT_CH0_LCTRL_MODE_U2_V << PCNT_CH0_LCTRL_MODE_U2_S)
+#define PCNT_CH0_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U2 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_M  (PCNT_CH0_HCTRL_MODE_U2_V << PCNT_CH0_HCTRL_MODE_U2_S)
+#define PCNT_CH0_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_S  20
+
+/* PCNT_CH0_POS_MODE_U2 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U2    0x00000003
+#define PCNT_CH0_POS_MODE_U2_M  (PCNT_CH0_POS_MODE_U2_V << PCNT_CH0_POS_MODE_U2_S)
+#define PCNT_CH0_POS_MODE_U2_V  0x00000003
+#define PCNT_CH0_POS_MODE_U2_S  18
+
+/* PCNT_CH0_NEG_MODE_U2 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U2    0x00000003
+#define PCNT_CH0_NEG_MODE_U2_M  (PCNT_CH0_NEG_MODE_U2_V << PCNT_CH0_NEG_MODE_U2_S)
+#define PCNT_CH0_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U2_S  16
+
+/* PCNT_THR_THRES1_EN_U2 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 2's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U2    (BIT(15))
+#define PCNT_THR_THRES1_EN_U2_M  (PCNT_THR_THRES1_EN_U2_V << PCNT_THR_THRES1_EN_U2_S)
+#define PCNT_THR_THRES1_EN_U2_V  0x00000001
+#define PCNT_THR_THRES1_EN_U2_S  15
+
+/* PCNT_THR_THRES0_EN_U2 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 2's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U2    (BIT(14))
+#define PCNT_THR_THRES0_EN_U2_M  (PCNT_THR_THRES0_EN_U2_V << PCNT_THR_THRES0_EN_U2_S)
+#define PCNT_THR_THRES0_EN_U2_V  0x00000001
+#define PCNT_THR_THRES0_EN_U2_S  14
+
+/* PCNT_THR_L_LIM_EN_U2 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 2's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U2    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U2_M  (PCNT_THR_L_LIM_EN_U2_V << PCNT_THR_L_LIM_EN_U2_S)
+#define PCNT_THR_L_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U2_S  13
+
+/* PCNT_THR_H_LIM_EN_U2 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 2's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U2    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U2_M  (PCNT_THR_H_LIM_EN_U2_V << PCNT_THR_H_LIM_EN_U2_S)
+#define PCNT_THR_H_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U2_S  12
+
+/* PCNT_THR_ZERO_EN_U2 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 2's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U2    (BIT(11))
+#define PCNT_THR_ZERO_EN_U2_M  (PCNT_THR_ZERO_EN_U2_V << PCNT_THR_ZERO_EN_U2_S)
+#define PCNT_THR_ZERO_EN_U2_V  0x00000001
+#define PCNT_THR_ZERO_EN_U2_S  11
+
+/* PCNT_FILTER_EN_U2 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 2's input filter.
+ */
+
+#define PCNT_FILTER_EN_U2    (BIT(10))
+#define PCNT_FILTER_EN_U2_M  (PCNT_FILTER_EN_U2_V << PCNT_FILTER_EN_U2_S)
+#define PCNT_FILTER_EN_U2_V  0x00000001
+#define PCNT_FILTER_EN_U2_S  10
+
+/* PCNT_FILTER_THRES_U2 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U2    0x000003ff
+#define PCNT_FILTER_THRES_U2_M  (PCNT_FILTER_THRES_U2_V << PCNT_FILTER_THRES_U2_S)
+#define PCNT_FILTER_THRES_U2_V  0x000003ff
+#define PCNT_FILTER_THRES_U2_S  0
+
+/* PCNT_U2_CONF1_REG register
+ * Configuration register 1 for unit 2
+ */
+
+#define PCNT_U2_CONF1_REG (DR_REG_PCNT_BASE + 0x1c)
+
+/* PCNT_CNT_THRES1_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES1_U2    0x0000ffff
+#define PCNT_CNT_THRES1_U2_M  (PCNT_CNT_THRES1_U2_V << PCNT_CNT_THRES1_U2_S)
+#define PCNT_CNT_THRES1_U2_V  0x0000ffff
+#define PCNT_CNT_THRES1_U2_S  16
+
+/* PCNT_CNT_THRES0_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES0_U2    0x0000ffff
+#define PCNT_CNT_THRES0_U2_M  (PCNT_CNT_THRES0_U2_V << PCNT_CNT_THRES0_U2_S)
+#define PCNT_CNT_THRES0_U2_V  0x0000ffff
+#define PCNT_CNT_THRES0_U2_S  0
+
+/* PCNT_U2_CONF2_REG register
+ * Configuration register 2 for unit 2
+ */
+
+#define PCNT_U2_CONF2_REG (DR_REG_PCNT_BASE + 0x20)
+
+/* PCNT_CNT_L_LIM_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 2.
+ */
+
+#define PCNT_CNT_L_LIM_U2    0x0000ffff
+#define PCNT_CNT_L_LIM_U2_M  (PCNT_CNT_L_LIM_U2_V << PCNT_CNT_L_LIM_U2_S)
+#define PCNT_CNT_L_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U2_S  16
+
+/* PCNT_CNT_H_LIM_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 2.
+ */
+
+#define PCNT_CNT_H_LIM_U2    0x0000ffff
+#define PCNT_CNT_H_LIM_U2_M  (PCNT_CNT_H_LIM_U2_V << PCNT_CNT_H_LIM_U2_S)
+#define PCNT_CNT_H_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U2_S  0
+
+/* PCNT_U3_CONF0_REG register
+ * Configuration register 0 for unit 3
+ */
+
+#define PCNT_U3_CONF0_REG (DR_REG_PCNT_BASE + 0x24)
+
+/* PCNT_CH1_LCTRL_MODE_U3 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_M  (PCNT_CH1_LCTRL_MODE_U3_V << PCNT_CH1_LCTRL_MODE_U3_S)
+#define PCNT_CH1_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U3 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_M  (PCNT_CH1_HCTRL_MODE_U3_V << PCNT_CH1_HCTRL_MODE_U3_S)
+#define PCNT_CH1_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_S  28
+
+/* PCNT_CH1_POS_MODE_U3 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U3    0x00000003
+#define PCNT_CH1_POS_MODE_U3_M  (PCNT_CH1_POS_MODE_U3_V << PCNT_CH1_POS_MODE_U3_S)
+#define PCNT_CH1_POS_MODE_U3_V  0x00000003
+#define PCNT_CH1_POS_MODE_U3_S  26
+
+/* PCNT_CH1_NEG_MODE_U3 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U3    0x00000003
+#define PCNT_CH1_NEG_MODE_U3_M  (PCNT_CH1_NEG_MODE_U3_V << PCNT_CH1_NEG_MODE_U3_S)
+#define PCNT_CH1_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U3_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U3 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_M  (PCNT_CH0_LCTRL_MODE_U3_V << PCNT_CH0_LCTRL_MODE_U3_S)
+#define PCNT_CH0_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U3 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_M  (PCNT_CH0_HCTRL_MODE_U3_V << PCNT_CH0_HCTRL_MODE_U3_S)
+#define PCNT_CH0_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_S  20
+
+/* PCNT_CH0_POS_MODE_U3 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U3    0x00000003
+#define PCNT_CH0_POS_MODE_U3_M  (PCNT_CH0_POS_MODE_U3_V << PCNT_CH0_POS_MODE_U3_S)
+#define PCNT_CH0_POS_MODE_U3_V  0x00000003
+#define PCNT_CH0_POS_MODE_U3_S  18
+
+/* PCNT_CH0_NEG_MODE_U3 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U3    0x00000003
+#define PCNT_CH0_NEG_MODE_U3_M  (PCNT_CH0_NEG_MODE_U3_V << PCNT_CH0_NEG_MODE_U3_S)
+#define PCNT_CH0_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U3_S  16
+
+/* PCNT_THR_THRES1_EN_U3 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 3's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U3    (BIT(15))
+#define PCNT_THR_THRES1_EN_U3_M  (PCNT_THR_THRES1_EN_U3_V << PCNT_THR_THRES1_EN_U3_S)
+#define PCNT_THR_THRES1_EN_U3_V  0x00000001
+#define PCNT_THR_THRES1_EN_U3_S  15
+
+/* PCNT_THR_THRES0_EN_U3 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 3's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U3    (BIT(14))
+#define PCNT_THR_THRES0_EN_U3_M  (PCNT_THR_THRES0_EN_U3_V << PCNT_THR_THRES0_EN_U3_S)
+#define PCNT_THR_THRES0_EN_U3_V  0x00000001
+#define PCNT_THR_THRES0_EN_U3_S  14
+
+/* PCNT_THR_L_LIM_EN_U3 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 3's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U3    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U3_M  (PCNT_THR_L_LIM_EN_U3_V << PCNT_THR_L_LIM_EN_U3_S)
+#define PCNT_THR_L_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U3_S  13
+
+/* PCNT_THR_H_LIM_EN_U3 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 3's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U3    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U3_M  (PCNT_THR_H_LIM_EN_U3_V << PCNT_THR_H_LIM_EN_U3_S)
+#define PCNT_THR_H_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U3_S  12
+
+/* PCNT_THR_ZERO_EN_U3 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 3's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U3    (BIT(11))
+#define PCNT_THR_ZERO_EN_U3_M  (PCNT_THR_ZERO_EN_U3_V << PCNT_THR_ZERO_EN_U3_S)
+#define PCNT_THR_ZERO_EN_U3_V  0x00000001
+#define PCNT_THR_ZERO_EN_U3_S  11
+
+/* PCNT_FILTER_EN_U3 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 3's input filter.
+ */
+
+#define PCNT_FILTER_EN_U3    (BIT(10))
+#define PCNT_FILTER_EN_U3_M  (PCNT_FILTER_EN_U3_V << PCNT_FILTER_EN_U3_S)
+#define PCNT_FILTER_EN_U3_V  0x00000001
+#define PCNT_FILTER_EN_U3_S  10
+
+/* PCNT_FILTER_THRES_U3 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U3    0x000003ff
+#define PCNT_FILTER_THRES_U3_M  (PCNT_FILTER_THRES_U3_V << PCNT_FILTER_THRES_U3_S)
+#define PCNT_FILTER_THRES_U3_V  0x000003ff
+#define PCNT_FILTER_THRES_U3_S  0
+
+/* PCNT_U3_CONF1_REG register
+ * Configuration register 1 for unit 3
+ */
+
+#define PCNT_U3_CONF1_REG (DR_REG_PCNT_BASE + 0x28)
+
+/* PCNT_CNT_THRES1_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES1_U3    0x0000ffff
+#define PCNT_CNT_THRES1_U3_M  (PCNT_CNT_THRES1_U3_V << PCNT_CNT_THRES1_U3_S)
+#define PCNT_CNT_THRES1_U3_V  0x0000ffff
+#define PCNT_CNT_THRES1_U3_S  16
+
+/* PCNT_CNT_THRES0_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES0_U3    0x0000ffff
+#define PCNT_CNT_THRES0_U3_M  (PCNT_CNT_THRES0_U3_V << PCNT_CNT_THRES0_U3_S)
+#define PCNT_CNT_THRES0_U3_V  0x0000ffff
+#define PCNT_CNT_THRES0_U3_S  0
+
+/* PCNT_U3_CONF2_REG register
+ * Configuration register 2 for unit 3
+ */
+
+#define PCNT_U3_CONF2_REG (DR_REG_PCNT_BASE + 0x2c)
+
+/* PCNT_CNT_L_LIM_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 3.
+ */
+
+#define PCNT_CNT_L_LIM_U3    0x0000ffff
+#define PCNT_CNT_L_LIM_U3_M  (PCNT_CNT_L_LIM_U3_V << PCNT_CNT_L_LIM_U3_S)
+#define PCNT_CNT_L_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U3_S  16
+
+/* PCNT_CNT_H_LIM_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 3.
+ */
+
+#define PCNT_CNT_H_LIM_U3    0x0000ffff
+#define PCNT_CNT_H_LIM_U3_M  (PCNT_CNT_H_LIM_U3_V << PCNT_CNT_H_LIM_U3_S)
+#define PCNT_CNT_H_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U3_S  0
+
+#define PCNT_U4_CONF0_REG          (DR_REG_PCNT_BASE + 0x0030)
+
+/* PCNT_CH1_LCTRL_MODE_U4 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U4_M  ((PCNT_CH1_LCTRL_MODE_U4_V)<<(PCNT_CH1_LCTRL_MODE_U4_S))
+#define PCNT_CH1_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U4_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U4 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U4_M  ((PCNT_CH1_HCTRL_MODE_U4_V)<<(PCNT_CH1_HCTRL_MODE_U4_S))
+#define PCNT_CH1_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U4_S  28
+
+/* PCNT_CH1_POS_MODE_U4 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U4  0x00000003
+#define PCNT_CH1_POS_MODE_U4_M  ((PCNT_CH1_POS_MODE_U4_V)<<(PCNT_CH1_POS_MODE_U4_S))
+#define PCNT_CH1_POS_MODE_U4_V  0x3
+#define PCNT_CH1_POS_MODE_U4_S  26
+
+/* PCNT_CH1_NEG_MODE_U4 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U4  0x00000003
+#define PCNT_CH1_NEG_MODE_U4_M  ((PCNT_CH1_NEG_MODE_U4_V)<<(PCNT_CH1_NEG_MODE_U4_S))
+#define PCNT_CH1_NEG_MODE_U4_V  0x3
+#define PCNT_CH1_NEG_MODE_U4_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U4 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U4_M  ((PCNT_CH0_LCTRL_MODE_U4_V)<<(PCNT_CH0_LCTRL_MODE_U4_S))
+#define PCNT_CH0_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U4_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U4 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U4_M  ((PCNT_CH0_HCTRL_MODE_U4_V)<<(PCNT_CH0_HCTRL_MODE_U4_S))
+#define PCNT_CH0_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U4_S  20
+
+/* PCNT_CH0_POS_MODE_U4 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U4  0x00000003
+#define PCNT_CH0_POS_MODE_U4_M  ((PCNT_CH0_POS_MODE_U4_V)<<(PCNT_CH0_POS_MODE_U4_S))
+#define PCNT_CH0_POS_MODE_U4_V  0x3
+#define PCNT_CH0_POS_MODE_U4_S  18
+
+/* PCNT_CH0_NEG_MODE_U4 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U4  0x00000003
+#define PCNT_CH0_NEG_MODE_U4_M  ((PCNT_CH0_NEG_MODE_U4_V)<<(PCNT_CH0_NEG_MODE_U4_S))
+#define PCNT_CH0_NEG_MODE_U4_V  0x3
+#define PCNT_CH0_NEG_MODE_U4_S  16
+
+/* PCNT_THR_THRES1_EN_U4 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U4  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_V  0x1
+#define PCNT_THR_THRES1_EN_U4_S  15
+
+/* PCNT_THR_THRES0_EN_U4 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U4  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_V  0x1
+#define PCNT_THR_THRES0_EN_U4_S  14
+
+/* PCNT_THR_L_LIM_EN_U4 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_l_lim  value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U4  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_V  0x1
+#define PCNT_THR_L_LIM_EN_U4_S  13
+
+/* PCNT_THR_H_LIM_EN_U4 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U4  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_V  0x1
+#define PCNT_THR_H_LIM_EN_U4_S  12
+
+/* PCNT_THR_ZERO_EN_U4 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U4  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_V  0x1
+#define PCNT_THR_ZERO_EN_U4_S  11
+
+/* PCNT_FILTER_EN_U4 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit4.
+ */
+
+#define PCNT_FILTER_EN_U4  (BIT(10))
+#define PCNT_FILTER_EN_U4_M  (BIT(10))
+#define PCNT_FILTER_EN_U4_V  0x1
+#define PCNT_FILTER_EN_U4_S  10
+
+/* PCNT_FILTER_THRES_U4 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit4.
+ */
+
+#define PCNT_FILTER_THRES_U4  0x000003FF
+#define PCNT_FILTER_THRES_U4_M  ((PCNT_FILTER_THRES_U4_V)<<(PCNT_FILTER_THRES_U4_S))
+#define PCNT_FILTER_THRES_U4_V  0x3FF
+#define PCNT_FILTER_THRES_U4_S  0
+
+#define PCNT_U4_CONF1_REG          (DR_REG_PCNT_BASE + 0x0034)
+
+/* PCNT_CNT_THRES1_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure thres1 value for unit4.
+ */
+
+#define PCNT_CNT_THRES1_U4  0x0000FFFF
+#define PCNT_CNT_THRES1_U4_M  ((PCNT_CNT_THRES1_U4_V)<<(PCNT_CNT_THRES1_U4_S))
+#define PCNT_CNT_THRES1_U4_V  0xFFFF
+#define PCNT_CNT_THRES1_U4_S  16
+
+/* PCNT_CNT_THRES0_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit4.
+ */
+
+#define PCNT_CNT_THRES0_U4  0x0000FFFF
+#define PCNT_CNT_THRES0_U4_M  ((PCNT_CNT_THRES0_U4_V)<<(PCNT_CNT_THRES0_U4_S))
+#define PCNT_CNT_THRES0_U4_V  0xFFFF
+#define PCNT_CNT_THRES0_U4_S  0
+
+#define PCNT_U4_CONF2_REG          (DR_REG_PCNT_BASE + 0x0038)
+
+/* PCNT_CNT_L_LIM_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit4.
+ */
+
+#define PCNT_CNT_L_LIM_U4  0x0000FFFF
+#define PCNT_CNT_L_LIM_U4_M  ((PCNT_CNT_L_LIM_U4_V)<<(PCNT_CNT_L_LIM_U4_S))
+#define PCNT_CNT_L_LIM_U4_V  0xFFFF
+#define PCNT_CNT_L_LIM_U4_S  16
+
+/* PCNT_CNT_H_LIM_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit4.
+ */
+
+#define PCNT_CNT_H_LIM_U4  0x0000FFFF
+#define PCNT_CNT_H_LIM_U4_M  ((PCNT_CNT_H_LIM_U4_V)<<(PCNT_CNT_H_LIM_U4_S))
+#define PCNT_CNT_H_LIM_U4_V  0xFFFF
+#define PCNT_CNT_H_LIM_U4_S  0
+
+#define PCNT_U5_CONF0_REG          (DR_REG_PCNT_BASE + 0x003c)
+
+/* PCNT_CH1_LCTRL_MODE_U5 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U5_M  ((PCNT_CH1_LCTRL_MODE_U5_V)<<(PCNT_CH1_LCTRL_MODE_U5_S))
+#define PCNT_CH1_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U5_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U5 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U5_M  ((PCNT_CH1_HCTRL_MODE_U5_V)<<(PCNT_CH1_HCTRL_MODE_U5_S))
+#define PCNT_CH1_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U5_S  28
+
+/* PCNT_CH1_POS_MODE_U5 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U5  0x00000003
+#define PCNT_CH1_POS_MODE_U5_M  ((PCNT_CH1_POS_MODE_U5_V)<<(PCNT_CH1_POS_MODE_U5_S))
+#define PCNT_CH1_POS_MODE_U5_V  0x3
+#define PCNT_CH1_POS_MODE_U5_S  26
+
+/* PCNT_CH1_NEG_MODE_U5 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U5  0x00000003
+#define PCNT_CH1_NEG_MODE_U5_M  ((PCNT_CH1_NEG_MODE_U5_V)<<(PCNT_CH1_NEG_MODE_U5_S))
+#define PCNT_CH1_NEG_MODE_U5_V  0x3
+#define PCNT_CH1_NEG_MODE_U5_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U5 : R/W ;bitpos:[23:22] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U5_M  ((PCNT_CH0_LCTRL_MODE_U5_V)<<(PCNT_CH0_LCTRL_MODE_U5_S))
+#define PCNT_CH0_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U5_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U5 : R/W ;bitpos:[21:20] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's high
+ * control signal for unit5.
+ * 0:increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U5_M  ((PCNT_CH0_HCTRL_MODE_U5_V)<<(PCNT_CH0_HCTRL_MODE_U5_S))
+#define PCNT_CH0_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U5_S  20
+
+/* PCNT_CH0_POS_MODE_U5 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U5  0x00000003
+#define PCNT_CH0_POS_MODE_U5_M  ((PCNT_CH0_POS_MODE_U5_V)<<(PCNT_CH0_POS_MODE_U5_S))
+#define PCNT_CH0_POS_MODE_U5_V  0x3
+#define PCNT_CH0_POS_MODE_U5_S  18
+
+/* PCNT_CH0_NEG_MODE_U5 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U5  0x00000003
+#define PCNT_CH0_NEG_MODE_U5_M  ((PCNT_CH0_NEG_MODE_U5_V)<<(PCNT_CH0_NEG_MODE_U5_S))
+#define PCNT_CH0_NEG_MODE_U5_V  0x3
+#define PCNT_CH0_NEG_MODE_U5_S  16
+
+/* PCNT_THR_THRES1_EN_U5 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U5  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_V  0x1
+#define PCNT_THR_THRES1_EN_U5_S  15
+
+/* PCNT_THR_THRES0_EN_U5 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U5  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_V  0x1
+#define PCNT_THR_THRES0_EN_U5_S  14
+
+/* PCNT_THR_L_LIM_EN_U5 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U5  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_V  0x1
+#define PCNT_THR_L_LIM_EN_U5_S  13
+
+/* PCNT_THR_H_LIM_EN_U5 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U5  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_V  0x1
+#define PCNT_THR_H_LIM_EN_U5_S  12
+
+/* PCNT_THR_ZERO_EN_U5 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U5  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_V  0x1
+#define PCNT_THR_ZERO_EN_U5_S  11
+
+/* PCNT_FILTER_EN_U5 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit5.
+ */
+
+#define PCNT_FILTER_EN_U5  (BIT(10))
+#define PCNT_FILTER_EN_U5_M  (BIT(10))
+#define PCNT_FILTER_EN_U5_V  0x1
+#define PCNT_FILTER_EN_U5_S  10
+
+/* PCNT_FILTER_THRES_U5 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit5.
+ */
+
+#define PCNT_FILTER_THRES_U5  0x000003FF
+#define PCNT_FILTER_THRES_U5_M  ((PCNT_FILTER_THRES_U5_V)<<(PCNT_FILTER_THRES_U5_S))
+#define PCNT_FILTER_THRES_U5_V  0x3FF
+#define PCNT_FILTER_THRES_U5_S  0
+
+#define PCNT_U5_CONF1_REG          (DR_REG_PCNT_BASE + 0x0040)
+
+/* PCNT_CNT_THRES1_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit5.
+ */
+
+#define PCNT_CNT_THRES1_U5  0x0000FFFF
+#define PCNT_CNT_THRES1_U5_M  ((PCNT_CNT_THRES1_U5_V)<<(PCNT_CNT_THRES1_U5_S))
+#define PCNT_CNT_THRES1_U5_V  0xFFFF
+#define PCNT_CNT_THRES1_U5_S  16
+
+/* PCNT_CNT_THRES0_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit5.
+ */
+
+#define PCNT_CNT_THRES0_U5  0x0000FFFF
+#define PCNT_CNT_THRES0_U5_M  ((PCNT_CNT_THRES0_U5_V)<<(PCNT_CNT_THRES0_U5_S))
+#define PCNT_CNT_THRES0_U5_V  0xFFFF
+#define PCNT_CNT_THRES0_U5_S  0
+
+#define PCNT_U5_CONF2_REG          (DR_REG_PCNT_BASE + 0x0044)
+
+/* PCNT_CNT_L_LIM_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit5.
+ */
+
+#define PCNT_CNT_L_LIM_U5  0x0000FFFF
+#define PCNT_CNT_L_LIM_U5_M  ((PCNT_CNT_L_LIM_U5_V)<<(PCNT_CNT_L_LIM_U5_S))
+#define PCNT_CNT_L_LIM_U5_V  0xFFFF
+#define PCNT_CNT_L_LIM_U5_S  16
+
+/* PCNT_CNT_H_LIM_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit5.
+ */
+
+#define PCNT_CNT_H_LIM_U5  0x0000FFFF
+#define PCNT_CNT_H_LIM_U5_M  ((PCNT_CNT_H_LIM_U5_V)<<(PCNT_CNT_H_LIM_U5_S))
+#define PCNT_CNT_H_LIM_U5_V  0xFFFF
+#define PCNT_CNT_H_LIM_U5_S  0
+
+#define PCNT_U6_CONF0_REG          (DR_REG_PCNT_BASE + 0x0048)
+
+/* PCNT_CH1_LCTRL_MODE_U6 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * low control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U6_M  ((PCNT_CH1_LCTRL_MODE_U6_V)<<(PCNT_CH1_LCTRL_MODE_U6_S))
+#define PCNT_CH1_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U6_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U6 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U6_M  ((PCNT_CH1_HCTRL_MODE_U6_V)<<(PCNT_CH1_HCTRL_MODE_U6_S))
+#define PCNT_CH1_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U6_S  28
+
+/* PCNT_CH1_POS_MODE_U6 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U6  0x00000003
+#define PCNT_CH1_POS_MODE_U6_M  ((PCNT_CH1_POS_MODE_U6_V)<<(PCNT_CH1_POS_MODE_U6_S))
+#define PCNT_CH1_POS_MODE_U6_V  0x3
+#define PCNT_CH1_POS_MODE_U6_S  26
+
+/* PCNT_CH1_NEG_MODE_U6 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * input negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U6  0x00000003
+#define PCNT_CH1_NEG_MODE_U6_M  ((PCNT_CH1_NEG_MODE_U6_V)<<(PCNT_CH1_NEG_MODE_U6_S))
+#define PCNT_CH1_NEG_MODE_U6_V  0x3
+#define PCNT_CH1_NEG_MODE_U6_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U6 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U6_M  ((PCNT_CH0_LCTRL_MODE_U6_V)<<(PCNT_CH0_LCTRL_MODE_U6_S))
+#define PCNT_CH0_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U6_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U6 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * high control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U6_M  ((PCNT_CH0_HCTRL_MODE_U6_V)<<(PCNT_CH0_HCTRL_MODE_U6_S))
+#define PCNT_CH0_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U6_S  20
+
+/* PCNT_CH0_POS_MODE_U6 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U6  0x00000003
+#define PCNT_CH0_POS_MODE_U6_M  ((PCNT_CH0_POS_MODE_U6_V)<<(PCNT_CH0_POS_MODE_U6_S))
+#define PCNT_CH0_POS_MODE_U6_V  0x3
+#define PCNT_CH0_POS_MODE_U6_S  18
+
+/* PCNT_CH0_NEG_MODE_U6 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U6  0x00000003
+#define PCNT_CH0_NEG_MODE_U6_M  ((PCNT_CH0_NEG_MODE_U6_V)<<(PCNT_CH0_NEG_MODE_U6_S))
+#define PCNT_CH0_NEG_MODE_U6_V  0x3
+#define PCNT_CH0_NEG_MODE_U6_S  16
+
+/* PCNT_THR_THRES1_EN_U6 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit6's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U6  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_V  0x1
+#define PCNT_THR_THRES1_EN_U6_S  15
+
+/* PCNT_THR_THRES0_EN_U6 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U6  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_V  0x1
+#define PCNT_THR_THRES0_EN_U6_S  14
+
+/* PCNT_THR_L_LIM_EN_U6 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U6  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_V  0x1
+#define PCNT_THR_L_LIM_EN_U6_S  13
+
+/* PCNT_THR_H_LIM_EN_U6 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit6's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U6  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_V  0x1
+#define PCNT_THR_H_LIM_EN_U6_S  12
+
+/* PCNT_THR_ZERO_EN_U6 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U6  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_V  0x1
+#define PCNT_THR_ZERO_EN_U6_S  11
+
+/* PCNT_FILTER_EN_U6 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit6.
+ */
+
+#define PCNT_FILTER_EN_U6  (BIT(10))
+#define PCNT_FILTER_EN_U6_M  (BIT(10))
+#define PCNT_FILTER_EN_U6_V  0x1
+#define PCNT_FILTER_EN_U6_S  10
+
+/* PCNT_FILTER_THRES_U6 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is
+ * smaller than this value for unit6.
+ */
+
+#define PCNT_FILTER_THRES_U6  0x000003FF
+#define PCNT_FILTER_THRES_U6_M  ((PCNT_FILTER_THRES_U6_V)<<(PCNT_FILTER_THRES_U6_S))
+#define PCNT_FILTER_THRES_U6_V  0x3FF
+#define PCNT_FILTER_THRES_U6_S  0
+
+#define PCNT_U6_CONF1_REG          (DR_REG_PCNT_BASE + 0x004c)
+
+/* PCNT_CNT_THRES1_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit6.
+ */
+
+#define PCNT_CNT_THRES1_U6  0x0000FFFF
+#define PCNT_CNT_THRES1_U6_M  ((PCNT_CNT_THRES1_U6_V)<<(PCNT_CNT_THRES1_U6_S))
+#define PCNT_CNT_THRES1_U6_V  0xFFFF
+#define PCNT_CNT_THRES1_U6_S  16
+
+/* PCNT_CNT_THRES0_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit6.
+ */
+
+#define PCNT_CNT_THRES0_U6  0x0000FFFF
+#define PCNT_CNT_THRES0_U6_M  ((PCNT_CNT_THRES0_U6_V)<<(PCNT_CNT_THRES0_U6_S))
+#define PCNT_CNT_THRES0_U6_V  0xFFFF
+#define PCNT_CNT_THRES0_U6_S  0
+
+#define PCNT_U6_CONF2_REG          (DR_REG_PCNT_BASE + 0x0050)
+
+/* PCNT_CNT_L_LIM_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit6.
+ */
+
+#define PCNT_CNT_L_LIM_U6  0x0000FFFF
+#define PCNT_CNT_L_LIM_U6_M  ((PCNT_CNT_L_LIM_U6_V)<<(PCNT_CNT_L_LIM_U6_S))
+#define PCNT_CNT_L_LIM_U6_V  0xFFFF
+#define PCNT_CNT_L_LIM_U6_S  16
+
+/* PCNT_CNT_H_LIM_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit6.
+ */
+
+#define PCNT_CNT_H_LIM_U6  0x0000FFFF
+#define PCNT_CNT_H_LIM_U6_M  ((PCNT_CNT_H_LIM_U6_V)<<(PCNT_CNT_H_LIM_U6_S))
+#define PCNT_CNT_H_LIM_U6_V  0xFFFF
+#define PCNT_CNT_H_LIM_U6_S  0
+
+#define PCNT_U7_CONF0_REG          (DR_REG_PCNT_BASE + 0x0054)
+
+/* PCNT_CH1_LCTRL_MODE_U7 : R/W ;bitpos:[31:30] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U7_M  ((PCNT_CH1_LCTRL_MODE_U7_V)<<(PCNT_CH1_LCTRL_MODE_U7_S))
+#define PCNT_CH1_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U7_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U7 : R/W ;bitpos:[29:28] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U7_M  ((PCNT_CH1_HCTRL_MODE_U7_V)<<(PCNT_CH1_HCTRL_MODE_U7_S))
+#define PCNT_CH1_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U7_S  28
+
+/* PCNT_CH1_POS_MODE_U7 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2:decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U7  0x00000003
+#define PCNT_CH1_POS_MODE_U7_M  ((PCNT_CH1_POS_MODE_U7_V)<<(PCNT_CH1_POS_MODE_U7_S))
+#define PCNT_CH1_POS_MODE_U7_V  0x3
+#define PCNT_CH1_POS_MODE_U7_S  26
+
+/* PCNT_CH1_NEG_MODE_U7 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U7  0x00000003
+#define PCNT_CH1_NEG_MODE_U7_M  ((PCNT_CH1_NEG_MODE_U7_V)<<(PCNT_CH1_NEG_MODE_U7_S))
+#define PCNT_CH1_NEG_MODE_U7_V  0x3
+#define PCNT_CH1_NEG_MODE_U7_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U7 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U7_M  ((PCNT_CH0_LCTRL_MODE_U7_V)<<(PCNT_CH0_LCTRL_MODE_U7_S))
+#define PCNT_CH0_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U7_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U7 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U7_M  ((PCNT_CH0_HCTRL_MODE_U7_V)<<(PCNT_CH0_HCTRL_MODE_U7_S))
+#define PCNT_CH0_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U7_S  20
+
+/* PCNT_CH0_POS_MODE_U7 : R/W ;bitpos:[19:18] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U7  0x00000003
+#define PCNT_CH0_POS_MODE_U7_M  ((PCNT_CH0_POS_MODE_U7_V)<<(PCNT_CH0_POS_MODE_U7_S))
+#define PCNT_CH0_POS_MODE_U7_V  0x3
+#define PCNT_CH0_POS_MODE_U7_S  18
+
+/* PCNT_CH0_NEG_MODE_U7 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * input negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U7  0x00000003
+#define PCNT_CH0_NEG_MODE_U7_M  ((PCNT_CH0_NEG_MODE_U7_V)<<(PCNT_CH0_NEG_MODE_U7_S))
+#define PCNT_CH0_NEG_MODE_U7_V  0x3
+#define PCNT_CH0_NEG_MODE_U7_S  16
+
+/* PCNT_THR_THRES1_EN_U7 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit7's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U7  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_V  0x1
+#define PCNT_THR_THRES1_EN_U7_S  15
+
+/* PCNT_THR_THRES0_EN_U7 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U7  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_V  0x1
+#define PCNT_THR_THRES0_EN_U7_S  14
+
+/* PCNT_THR_L_LIM_EN_U7 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U7  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_V  0x1
+#define PCNT_THR_L_LIM_EN_U7_S  13
+
+/* PCNT_THR_H_LIM_EN_U7 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit7's count
+ * with thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U7  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_V  0x1
+#define PCNT_THR_H_LIM_EN_U7_S  12
+
+/* PCNT_THR_ZERO_EN_U7 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U7  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_V  0x1
+#define PCNT_THR_ZERO_EN_U7_S  11
+
+/* PCNT_FILTER_EN_U7 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit7.
+ */
+
+#define PCNT_FILTER_EN_U7  (BIT(10))
+#define PCNT_FILTER_EN_U7_M  (BIT(10))
+#define PCNT_FILTER_EN_U7_V  0x1
+#define PCNT_FILTER_EN_U7_S  10
+
+/* PCNT_FILTER_THRES_U7 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit7.
+ */
+
+#define PCNT_FILTER_THRES_U7  0x000003FF
+#define PCNT_FILTER_THRES_U7_M  ((PCNT_FILTER_THRES_U7_V)<<(PCNT_FILTER_THRES_U7_S))
+#define PCNT_FILTER_THRES_U7_V  0x3FF
+#define PCNT_FILTER_THRES_U7_S  0
+
+#define PCNT_U7_CONF1_REG          (DR_REG_PCNT_BASE + 0x0058)
+
+/* PCNT_CNT_THRES1_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit7.
+ */
+
+#define PCNT_CNT_THRES1_U7  0x0000FFFF
+#define PCNT_CNT_THRES1_U7_M  ((PCNT_CNT_THRES1_U7_V)<<(PCNT_CNT_THRES1_U7_S))
+#define PCNT_CNT_THRES1_U7_V  0xFFFF
+#define PCNT_CNT_THRES1_U7_S  16
+
+/* PCNT_CNT_THRES0_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit7.
+ */
+
+#define PCNT_CNT_THRES0_U7  0x0000FFFF
+#define PCNT_CNT_THRES0_U7_M  ((PCNT_CNT_THRES0_U7_V)<<(PCNT_CNT_THRES0_U7_S))
+#define PCNT_CNT_THRES0_U7_V  0xFFFF
+#define PCNT_CNT_THRES0_U7_S  0
+
+#define PCNT_U7_CONF2_REG          (DR_REG_PCNT_BASE + 0x005c)
+
+/* PCNT_CNT_L_LIM_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit7.
+ */
+
+#define PCNT_CNT_L_LIM_U7  0x0000FFFF
+#define PCNT_CNT_L_LIM_U7_M  ((PCNT_CNT_L_LIM_U7_V)<<(PCNT_CNT_L_LIM_U7_S))
+#define PCNT_CNT_L_LIM_U7_V  0xFFFF
+#define PCNT_CNT_L_LIM_U7_S  16
+
+/* PCNT_CNT_H_LIM_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit7.
+ */
+
+#define PCNT_CNT_H_LIM_U7  0x0000FFFF
+#define PCNT_CNT_H_LIM_U7_M  ((PCNT_CNT_H_LIM_U7_V)<<(PCNT_CNT_H_LIM_U7_S))
+#define PCNT_CNT_H_LIM_U7_V  0xFFFF
+#define PCNT_CNT_H_LIM_U7_S  0
+
+#define PCNT_U0_CNT_REG          (DR_REG_PCNT_BASE + 0x0060)
+
+/* PCNT_PLUS_CNT_U0 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit0.
+ */
+
+#define PCNT_PLUS_CNT_U0  0x0000FFFF
+#define PCNT_PLUS_CNT_U0_M  ((PCNT_PLUS_CNT_U0_V)<<(PCNT_PLUS_CNT_U0_S))
+#define PCNT_PLUS_CNT_U0_V  0xFFFF
+#define PCNT_PLUS_CNT_U0_S  0
+
+#define PCNT_U1_CNT_REG          (DR_REG_PCNT_BASE + 0x0064)
+
+/* PCNT_PLUS_CNT_U1 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit1.
+ */
+
+#define PCNT_PLUS_CNT_U1  0x0000FFFF
+#define PCNT_PLUS_CNT_U1_M  ((PCNT_PLUS_CNT_U1_V)<<(PCNT_PLUS_CNT_U1_S))
+#define PCNT_PLUS_CNT_U1_V  0xFFFF
+#define PCNT_PLUS_CNT_U1_S  0
+
+#define PCNT_U2_CNT_REG          (DR_REG_PCNT_BASE + 0x0068)
+
+/* PCNT_PLUS_CNT_U2 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit2.
+ */
+
+#define PCNT_PLUS_CNT_U2  0x0000FFFF
+#define PCNT_PLUS_CNT_U2_M  ((PCNT_PLUS_CNT_U2_V)<<(PCNT_PLUS_CNT_U2_S))
+#define PCNT_PLUS_CNT_U2_V  0xFFFF
+#define PCNT_PLUS_CNT_U2_S  0
+
+#define PCNT_U3_CNT_REG          (DR_REG_PCNT_BASE + 0x006c)
+
+/* PCNT_PLUS_CNT_U3 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit3.
+ */
+
+#define PCNT_PLUS_CNT_U3  0x0000FFFF
+#define PCNT_PLUS_CNT_U3_M  ((PCNT_PLUS_CNT_U3_V)<<(PCNT_PLUS_CNT_U3_S))
+#define PCNT_PLUS_CNT_U3_V  0xFFFF
+#define PCNT_PLUS_CNT_U3_S  0
+
+#define PCNT_U4_CNT_REG          (DR_REG_PCNT_BASE + 0x0070)
+
+/* PCNT_PLUS_CNT_U4 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit4.
+ */
+
+#define PCNT_PLUS_CNT_U4  0x0000FFFF
+#define PCNT_PLUS_CNT_U4_M  ((PCNT_PLUS_CNT_U4_V)<<(PCNT_PLUS_CNT_U4_S))
+#define PCNT_PLUS_CNT_U4_V  0xFFFF
+#define PCNT_PLUS_CNT_U4_S  0
+
+#define PCNT_U5_CNT_REG          (DR_REG_PCNT_BASE + 0x0074)
+
+/* PCNT_PLUS_CNT_U5 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit5.
+ */
+
+#define PCNT_PLUS_CNT_U5  0x0000FFFF
+#define PCNT_PLUS_CNT_U5_M  ((PCNT_PLUS_CNT_U5_V)<<(PCNT_PLUS_CNT_U5_S))
+#define PCNT_PLUS_CNT_U5_V  0xFFFF
+#define PCNT_PLUS_CNT_U5_S  0
+
+#define PCNT_U6_CNT_REG          (DR_REG_PCNT_BASE + 0x0078)
+
+/* PCNT_PLUS_CNT_U6 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit6.
+ */
+
+#define PCNT_PLUS_CNT_U6  0x0000FFFF
+#define PCNT_PLUS_CNT_U6_M  ((PCNT_PLUS_CNT_U6_V)<<(PCNT_PLUS_CNT_U6_S))
+#define PCNT_PLUS_CNT_U6_V  0xFFFF
+#define PCNT_PLUS_CNT_U6_S  0
+
+#define PCNT_U7_CNT_REG          (DR_REG_PCNT_BASE + 0x007c)
+
+/* PCNT_PLUS_CNT_U7 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit7.
+ */
+
+#define PCNT_PLUS_CNT_U7  0x0000FFFF
+#define PCNT_PLUS_CNT_U7_M  ((PCNT_PLUS_CNT_U7_V)<<(PCNT_PLUS_CNT_U7_S))
+#define PCNT_PLUS_CNT_U7_V  0xFFFF
+#define PCNT_PLUS_CNT_U7_S  0
+
+#define PCNT_INT_RAW_REG          (DR_REG_PCNT_BASE + 0x0080)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_RAW : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_RAW : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_RAW : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_RAW : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_RAW : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_RAW : RO ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_RAW : RO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_RAW : RO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_S  0
+
+#define PCNT_INT_ST_REG          (DR_REG_PCNT_BASE + 0x0084)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ST : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ST  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ST : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ST  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ST : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ST  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ST  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ST : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ST  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ST : RO; bitpos: [2]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U2_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ST    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_M  (PCNT_CNT_THR_EVENT_U2_INT_ST_V << PCNT_CNT_THR_EVENT_U2_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ST : RO; bitpos: [1]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U1_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ST    (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_M  (PCNT_CNT_THR_EVENT_U1_INT_ST_V << PCNT_CNT_THR_EVENT_U1_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ST : RO; bitpos: [0]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U0_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ST    (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_M  (PCNT_CNT_THR_EVENT_U0_INT_ST_V << PCNT_CNT_THR_EVENT_U0_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_S  0
+
+/* PCNT_INT_ENA_REG register
+ * Interrupt enable register
+ */
+
+#define PCNT_INT_ENA_REG          (DR_REG_PCNT_BASE + 0x0088)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ENA : R/W ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ENA : R/W ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ENA : R/W ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ENA : R/W ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ENA : R/W ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ENA : R/W ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_S  0
+
+#define PCNT_INT_CLR_REG          (DR_REG_PCNT_BASE + 0x008c)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_CLR : WO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel7 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_CLR : WO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel6 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_CLR : WO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel5 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_CLR : WO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel4 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_CLR : WO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel3 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_CLR : WO; bitpos: [2]; default: 0;
+ * Set this bit to clear the PCNT_CNT_THR_EVENT_U2_INT interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_M  (PCNT_CNT_THR_EVENT_U2_INT_CLR_V << PCNT_CNT_THR_EVENT_U2_INT_CLR_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_CLR : WO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel1 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_CLR : WO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel0 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_S  0
+
+#define PCNT_U0_STATUS_REG          (DR_REG_PCNT_BASE + 0x0090)
+
+/* PCNT_CORE_STATUS_U0 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U0  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_M  ((PCNT_CORE_STATUS_U0_V)<<(PCNT_CORE_STATUS_U0_S))
+#define PCNT_CORE_STATUS_U0_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_S  0
+
+/* 0: positive value to zero;
+ * 1: negative value to zero;
+ * 2: counter value negative;
+ * 3: counter value positive
+ */
+
+#define PCNT_STATUS_CNT_MODE    0x3
+#define PCNT_STATUS_CNT_MODE_M  ((PCNT_STATUS_CNT_MODE_V)<<(PCNT_STATUS_CNT_MODE_S))
+#define PCNT_STATUS_CNT_MODE_V  0x3
+#define PCNT_STATUS_CNT_MODE_S  0
+
+/* counter value equals to thresh1 */
+
+#define PCNT_STATUS_THRES1    BIT(2)
+#define PCNT_STATUS_THRES1_M  BIT(2)
+#define PCNT_STATUS_THRES1_V  0x1
+#define PCNT_STATUS_THRES1_S  2
+
+/* counter value equals to thresh0 */
+
+#define PCNT_STATUS_THRES0    BIT(3)
+#define PCNT_STATUS_THRES0_M  BIT(3)
+#define PCNT_STATUS_THRES0_V  0x1
+#define PCNT_STATUS_THRES0_S  3
+
+/* counter value reaches h_lim */
+
+#define PCNT_STATUS_L_LIM    BIT(4)
+#define PCNT_STATUS_L_LIM_M  BIT(4)
+#define PCNT_STATUS_L_LIM_V  0x1
+#define PCNT_STATUS_L_LIM_S  4
+
+/* counter value reaches l_lim */
+
+#define PCNT_STATUS_H_LIM    BIT(5)
+#define PCNT_STATUS_H_LIM_M  BIT(5)
+#define PCNT_STATUS_H_LIM_V  0x1
+#define PCNT_STATUS_H_LIM_S  5
+
+/* counter value equals to zero */
+
+#define PCNT_STATUS_ZERO    BIT(6)
+#define PCNT_STATUS_ZERO_M  BIT(6)
+#define PCNT_STATUS_ZERO_V  0x1
+#define PCNT_STATUS_ZERO_S  6
+
+#define PCNT_U1_STATUS_REG          (DR_REG_PCNT_BASE + 0x0094)
+
+/* PCNT_CORE_STATUS_U1 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U1  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_M  ((PCNT_CORE_STATUS_U1_V)<<(PCNT_CORE_STATUS_U1_S))
+#define PCNT_CORE_STATUS_U1_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_S  0
+
+#define PCNT_U2_STATUS_REG          (DR_REG_PCNT_BASE + 0x0098)
+
+/* PCNT_CORE_STATUS_U2 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U2  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_M  ((PCNT_CORE_STATUS_U2_V)<<(PCNT_CORE_STATUS_U2_S))
+#define PCNT_CORE_STATUS_U2_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_S  0
+
+#define PCNT_U3_STATUS_REG          (DR_REG_PCNT_BASE + 0x009c)
+
+/* PCNT_CORE_STATUS_U3 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U3  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_M  ((PCNT_CORE_STATUS_U3_V)<<(PCNT_CORE_STATUS_U3_S))
+#define PCNT_CORE_STATUS_U3_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_S  0
+
+#define PCNT_U4_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a0)
+/* PCNT_CORE_STATUS_U4 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U4  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_M  ((PCNT_CORE_STATUS_U4_V)<<(PCNT_CORE_STATUS_U4_S))
+#define PCNT_CORE_STATUS_U4_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_S  0
+
+#define PCNT_U5_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a4)
+/* PCNT_CORE_STATUS_U5 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U5  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_M  ((PCNT_CORE_STATUS_U5_V)<<(PCNT_CORE_STATUS_U5_S))
+#define PCNT_CORE_STATUS_U5_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_S  0
+
+#define PCNT_U6_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a8)
+/* PCNT_CORE_STATUS_U6 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U6  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_M  ((PCNT_CORE_STATUS_U6_V)<<(PCNT_CORE_STATUS_U6_S))
+#define PCNT_CORE_STATUS_U6_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_S  0
+
+#define PCNT_U7_STATUS_REG          (DR_REG_PCNT_BASE + 0x00ac)
+
+/* PCNT_CORE_STATUS_U7 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U7  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_M  ((PCNT_CORE_STATUS_U7_V)<<(PCNT_CORE_STATUS_U7_S))
+#define PCNT_CORE_STATUS_U7_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_S  0
+
+#define PCNT_CTRL_REG          (DR_REG_PCNT_BASE + 0x00b0)
+
+/* PCNT_CLK_EN : R/W ;bitpos:[16] ;default: 1'b0 ; */
+
+#define PCNT_CLK_EN  (BIT(16))
+#define PCNT_CLK_EN_M  (BIT(16))
+#define PCNT_CLK_EN_V  0x1
+#define PCNT_CLK_EN_S  16
+
+/* PCNT_CNT_PAUSE_U7 : R/W ;bitpos:[15] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit7's counter. */
+
+#define PCNT_CNT_PAUSE_U7  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_M  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_V  0x1
+#define PCNT_CNT_PAUSE_U7_S  15
+
+/* PCNT_PLUS_CNT_RST_U7 : R/W ;bitpos:[14] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit7's counter. */
+
+#define PCNT_PLUS_CNT_RST_U7  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_M  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_V  0x1
+#define PCNT_PLUS_CNT_RST_U7_S  14
+
+/* PCNT_CNT_PAUSE_U6 : R/W ;bitpos:[13] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit6's counter. */
+
+#define PCNT_CNT_PAUSE_U6  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_M  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_V  0x1
+#define PCNT_CNT_PAUSE_U6_S  13
+
+/* PCNT_PLUS_CNT_RST_U6 : R/W ;bitpos:[12] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit6's counter. */
+
+#define PCNT_PLUS_CNT_RST_U6  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_M  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_V  0x1
+#define PCNT_PLUS_CNT_RST_U6_S  12
+
+/* PCNT_CNT_PAUSE_U5 : R/W ;bitpos:[11] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit5's counter. */
+
+#define PCNT_CNT_PAUSE_U5  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_M  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_V  0x1
+#define PCNT_CNT_PAUSE_U5_S  11
+
+/* PCNT_PLUS_CNT_RST_U5 : R/W ;bitpos:[10] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit5's counter. */
+
+#define PCNT_PLUS_CNT_RST_U5  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_M  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_V  0x1
+#define PCNT_PLUS_CNT_RST_U5_S  10
+
+/* PCNT_CNT_PAUSE_U4 : R/W ;bitpos:[9] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit4's counter. */
+
+#define PCNT_CNT_PAUSE_U4  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_M  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_V  0x1
+#define PCNT_CNT_PAUSE_U4_S  9
+
+/* PCNT_PLUS_CNT_RST_U4 : R/W ;bitpos:[8] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit4's counter. */
+
+#define PCNT_PLUS_CNT_RST_U4  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_M  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_V  0x1
+#define PCNT_PLUS_CNT_RST_U4_S  8
+
+/* PCNT_CNT_PAUSE_U3 : R/W ;bitpos:[7] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit3's counter. */
+
+#define PCNT_CNT_PAUSE_U3  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_M  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_V  0x1
+#define PCNT_CNT_PAUSE_U3_S  7
+
+/* PCNT_PLUS_CNT_RST_U3 : R/W ;bitpos:[6] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit3's counter. */
+
+#define PCNT_PLUS_CNT_RST_U3  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_M  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_V  0x1
+#define PCNT_PLUS_CNT_RST_U3_S  6
+
+/* PCNT_CNT_PAUSE_U2 : R/W ;bitpos:[5] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit2's counter. */
+
+#define PCNT_CNT_PAUSE_U2  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_M  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_V  0x1
+#define PCNT_CNT_PAUSE_U2_S  5
+
+/* PCNT_PLUS_CNT_RST_U2 : R/W ;bitpos:[4] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit2's counter. */
+
+#define PCNT_PLUS_CNT_RST_U2  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_M  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_V  0x1
+#define PCNT_PLUS_CNT_RST_U2_S  4
+
+/* PCNT_CNT_PAUSE_U1 : R/W ;bitpos:[3] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit1's counter. */
+
+#define PCNT_CNT_PAUSE_U1  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_M  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_V  0x1
+#define PCNT_CNT_PAUSE_U1_S  3
+
+/* PCNT_PLUS_CNT_RST_U1 : R/W ;bitpos:[2] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit1's counter. */
+
+#define PCNT_PLUS_CNT_RST_U1  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_M  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_V  0x1
+#define PCNT_PLUS_CNT_RST_U1_S  2
+
+/* PCNT_CNT_PAUSE_U0 : R/W ;bitpos:[1] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit0's counter. */
+
+#define PCNT_CNT_PAUSE_U0  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_M  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_V  0x1
+#define PCNT_CNT_PAUSE_U0_S  1
+
+/* PCNT_PLUS_CNT_RST_U0 : R/W ;bitpos:[0] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit0's counter. */
+
+#define PCNT_PLUS_CNT_RST_U0  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_M  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_V  0x1
+#define PCNT_PLUS_CNT_RST_U0_S  0
+
+#define PCNT_DATE_REG          (DR_REG_PCNT_BASE + 0x00fc)
+
+/* PCNT_DATE : R/W ;bitpos:[31:0] ;default: 32'h14122600 ; */
+
+#define PCNT_DATE    0xFFFFFFFF
+#define PCNT_DATE_M  ((PCNT_DATE_V)<<(PCNT_DATE_S))
+#define PCNT_DATE_V  0xFFFFFFFF
+#define PCNT_DATE_S  0
+
+/* Index macros for CONF0/1/2 */
+
+#define PCNT_CONF0_U(X)   PCNT_U0_CONF0_REG + (X * 12)
+#define PCNT_CONF1_U(X)   PCNT_U0_CONF1_REG + (X * 12)
+#define PCNT_CONF2_U(X)   PCNT_U0_CONF2_REG + (X * 12)
+
+/* Index macros for CONT */
+
+#define PCNT_CNT_U(X)     PCNT_U0_CNT_REG + (X * 4)
+
+/* Index macros for STATUS */
+
+#define PCNT_STATUS_U(X)  PCNT_U0_STATUS_REG + (X * 4)

Review Comment:
   ```suggestion
   #define PCNT_STATUS_U(X)  PCNT_U0_STATUS_REG + ((X) * 4)
   ```



##########
arch/xtensa/src/esp32/hardware/esp32_pcnt.h:
##########
@@ -0,0 +1,2495 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/hardware/esp32_pcnt.h
+ *
+ * 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_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+#define __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* PCNT_U0_CONF0_REG register
+ * Configuration register 0 for unit 0
+ */
+
+#define PCNT_U0_CONF0_REG (DR_REG_PCNT_BASE + 0x0)
+
+/* PCNT_CH1_LCTRL_MODE_U0 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_M  (PCNT_CH1_LCTRL_MODE_U0_V << PCNT_CH1_LCTRL_MODE_U0_S)
+#define PCNT_CH1_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U0 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_M  (PCNT_CH1_HCTRL_MODE_U0_V << PCNT_CH1_HCTRL_MODE_U0_S)
+#define PCNT_CH1_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_S  28
+
+/* PCNT_CH1_POS_MODE_U0 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U0    0x00000003
+#define PCNT_CH1_POS_MODE_U0_M  (PCNT_CH1_POS_MODE_U0_V << PCNT_CH1_POS_MODE_U0_S)
+#define PCNT_CH1_POS_MODE_U0_V  0x00000003
+#define PCNT_CH1_POS_MODE_U0_S  26
+
+/* PCNT_CH1_NEG_MODE_U0 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U0    0x00000003
+#define PCNT_CH1_NEG_MODE_U0_M  (PCNT_CH1_NEG_MODE_U0_V << PCNT_CH1_NEG_MODE_U0_S)
+#define PCNT_CH1_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U0_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U0 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_M  (PCNT_CH0_LCTRL_MODE_U0_V << PCNT_CH0_LCTRL_MODE_U0_S)
+#define PCNT_CH0_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U0 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_M  (PCNT_CH0_HCTRL_MODE_U0_V << PCNT_CH0_HCTRL_MODE_U0_S)
+#define PCNT_CH0_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_S  20
+
+/* PCNT_CH0_POS_MODE_U0 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U0    0x00000003
+#define PCNT_CH0_POS_MODE_U0_M  (PCNT_CH0_POS_MODE_U0_V << PCNT_CH0_POS_MODE_U0_S)
+#define PCNT_CH0_POS_MODE_U0_V  0x00000003
+#define PCNT_CH0_POS_MODE_U0_S  18
+
+/* PCNT_CH0_NEG_MODE_U0 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U0    0x00000003
+#define PCNT_CH0_NEG_MODE_U0_M  (PCNT_CH0_NEG_MODE_U0_V << PCNT_CH0_NEG_MODE_U0_S)
+#define PCNT_CH0_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U0_S  16
+
+/* PCNT_THR_THRES1_EN_U0 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 0's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U0    (BIT(15))
+#define PCNT_THR_THRES1_EN_U0_M  (PCNT_THR_THRES1_EN_U0_V << PCNT_THR_THRES1_EN_U0_S)
+#define PCNT_THR_THRES1_EN_U0_V  0x00000001
+#define PCNT_THR_THRES1_EN_U0_S  15
+
+/* PCNT_THR_THRES0_EN_U0 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 0's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U0    (BIT(14))
+#define PCNT_THR_THRES0_EN_U0_M  (PCNT_THR_THRES0_EN_U0_V << PCNT_THR_THRES0_EN_U0_S)
+#define PCNT_THR_THRES0_EN_U0_V  0x00000001
+#define PCNT_THR_THRES0_EN_U0_S  14
+
+/* PCNT_THR_L_LIM_EN_U0 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 0's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U0    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U0_M  (PCNT_THR_L_LIM_EN_U0_V << PCNT_THR_L_LIM_EN_U0_S)
+#define PCNT_THR_L_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U0_S  13
+
+/* PCNT_THR_H_LIM_EN_U0 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 0's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U0    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U0_M  (PCNT_THR_H_LIM_EN_U0_V << PCNT_THR_H_LIM_EN_U0_S)
+#define PCNT_THR_H_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U0_S  12
+
+/* PCNT_THR_ZERO_EN_U0 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 0's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U0    (BIT(11))
+#define PCNT_THR_ZERO_EN_U0_M  (PCNT_THR_ZERO_EN_U0_V << PCNT_THR_ZERO_EN_U0_S)
+#define PCNT_THR_ZERO_EN_U0_V  0x00000001
+#define PCNT_THR_ZERO_EN_U0_S  11
+
+/* PCNT_FILTER_EN_U0 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 0's input filter.
+ */
+
+#define PCNT_FILTER_EN_U0    (BIT(10))
+#define PCNT_FILTER_EN_U0_M  (PCNT_FILTER_EN_U0_V << PCNT_FILTER_EN_U0_S)
+#define PCNT_FILTER_EN_U0_V  0x00000001
+#define PCNT_FILTER_EN_U0_S  10
+
+/* PCNT_FILTER_THRES_U0 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U0    0x000003ff
+#define PCNT_FILTER_THRES_U0_M  (PCNT_FILTER_THRES_U0_V << PCNT_FILTER_THRES_U0_S)
+#define PCNT_FILTER_THRES_U0_V  0x000003ff
+#define PCNT_FILTER_THRES_U0_S  0
+
+/* PCNT_U0_CONF1_REG register
+ * Configuration register 1 for unit 0
+ */
+
+#define PCNT_U0_CONF1_REG (DR_REG_PCNT_BASE + 0x4)
+
+/* PCNT_CNT_THRES1_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES1_U0    0x0000ffff
+#define PCNT_CNT_THRES1_U0_M  (PCNT_CNT_THRES1_U0_V << PCNT_CNT_THRES1_U0_S)
+#define PCNT_CNT_THRES1_U0_V  0x0000ffff
+#define PCNT_CNT_THRES1_U0_S  16
+
+/* PCNT_CNT_THRES0_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES0_U0    0x0000ffff
+#define PCNT_CNT_THRES0_U0_M  (PCNT_CNT_THRES0_U0_V << PCNT_CNT_THRES0_U0_S)
+#define PCNT_CNT_THRES0_U0_V  0x0000ffff
+#define PCNT_CNT_THRES0_U0_S  0
+
+/* PCNT_U0_CONF2_REG register
+ * Configuration register 2 for unit 0
+ */
+
+#define PCNT_U0_CONF2_REG (DR_REG_PCNT_BASE + 0x8)
+
+/* PCNT_CNT_L_LIM_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 0.
+ */
+
+#define PCNT_CNT_L_LIM_U0    0x0000ffff
+#define PCNT_CNT_L_LIM_U0_M  (PCNT_CNT_L_LIM_U0_V << PCNT_CNT_L_LIM_U0_S)
+#define PCNT_CNT_L_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U0_S  16
+
+/* PCNT_CNT_H_LIM_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 0.
+ */
+
+#define PCNT_CNT_H_LIM_U0    0x0000ffff
+#define PCNT_CNT_H_LIM_U0_M  (PCNT_CNT_H_LIM_U0_V << PCNT_CNT_H_LIM_U0_S)
+#define PCNT_CNT_H_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U0_S  0
+
+/* PCNT_U1_CONF0_REG register
+ * Configuration register 0 for unit 1
+ */
+
+#define PCNT_U1_CONF0_REG (DR_REG_PCNT_BASE + 0xc)
+
+/* PCNT_CH1_LCTRL_MODE_U1 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_M  (PCNT_CH1_LCTRL_MODE_U1_V << PCNT_CH1_LCTRL_MODE_U1_S)
+#define PCNT_CH1_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U1 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_M  (PCNT_CH1_HCTRL_MODE_U1_V << PCNT_CH1_HCTRL_MODE_U1_S)
+#define PCNT_CH1_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_S  28
+
+/* PCNT_CH1_POS_MODE_U1 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U1    0x00000003
+#define PCNT_CH1_POS_MODE_U1_M  (PCNT_CH1_POS_MODE_U1_V << PCNT_CH1_POS_MODE_U1_S)
+#define PCNT_CH1_POS_MODE_U1_V  0x00000003
+#define PCNT_CH1_POS_MODE_U1_S  26
+
+/* PCNT_CH1_NEG_MODE_U1 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U1    0x00000003
+#define PCNT_CH1_NEG_MODE_U1_M  (PCNT_CH1_NEG_MODE_U1_V << PCNT_CH1_NEG_MODE_U1_S)
+#define PCNT_CH1_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U1_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U1 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_M  (PCNT_CH0_LCTRL_MODE_U1_V << PCNT_CH0_LCTRL_MODE_U1_S)
+#define PCNT_CH0_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U1 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_M  (PCNT_CH0_HCTRL_MODE_U1_V << PCNT_CH0_HCTRL_MODE_U1_S)
+#define PCNT_CH0_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_S  20
+
+/* PCNT_CH0_POS_MODE_U1 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U1    0x00000003
+#define PCNT_CH0_POS_MODE_U1_M  (PCNT_CH0_POS_MODE_U1_V << PCNT_CH0_POS_MODE_U1_S)
+#define PCNT_CH0_POS_MODE_U1_V  0x00000003
+#define PCNT_CH0_POS_MODE_U1_S  18
+
+/* PCNT_CH0_NEG_MODE_U1 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U1    0x00000003
+#define PCNT_CH0_NEG_MODE_U1_M  (PCNT_CH0_NEG_MODE_U1_V << PCNT_CH0_NEG_MODE_U1_S)
+#define PCNT_CH0_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U1_S  16
+
+/* PCNT_THR_THRES1_EN_U1 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 1's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U1    (BIT(15))
+#define PCNT_THR_THRES1_EN_U1_M  (PCNT_THR_THRES1_EN_U1_V << PCNT_THR_THRES1_EN_U1_S)
+#define PCNT_THR_THRES1_EN_U1_V  0x00000001
+#define PCNT_THR_THRES1_EN_U1_S  15
+
+/* PCNT_THR_THRES0_EN_U1 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 1's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U1    (BIT(14))
+#define PCNT_THR_THRES0_EN_U1_M  (PCNT_THR_THRES0_EN_U1_V << PCNT_THR_THRES0_EN_U1_S)
+#define PCNT_THR_THRES0_EN_U1_V  0x00000001
+#define PCNT_THR_THRES0_EN_U1_S  14
+
+/* PCNT_THR_L_LIM_EN_U1 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 1's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U1    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U1_M  (PCNT_THR_L_LIM_EN_U1_V << PCNT_THR_L_LIM_EN_U1_S)
+#define PCNT_THR_L_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U1_S  13
+
+/* PCNT_THR_H_LIM_EN_U1 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 1's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U1    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U1_M  (PCNT_THR_H_LIM_EN_U1_V << PCNT_THR_H_LIM_EN_U1_S)
+#define PCNT_THR_H_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U1_S  12
+
+/* PCNT_THR_ZERO_EN_U1 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 1's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U1    (BIT(11))
+#define PCNT_THR_ZERO_EN_U1_M  (PCNT_THR_ZERO_EN_U1_V << PCNT_THR_ZERO_EN_U1_S)
+#define PCNT_THR_ZERO_EN_U1_V  0x00000001
+#define PCNT_THR_ZERO_EN_U1_S  11
+
+/* PCNT_FILTER_EN_U1 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 1's input filter.
+ */
+
+#define PCNT_FILTER_EN_U1    (BIT(10))
+#define PCNT_FILTER_EN_U1_M  (PCNT_FILTER_EN_U1_V << PCNT_FILTER_EN_U1_S)
+#define PCNT_FILTER_EN_U1_V  0x00000001
+#define PCNT_FILTER_EN_U1_S  10
+
+/* PCNT_FILTER_THRES_U1 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U1    0x000003ff
+#define PCNT_FILTER_THRES_U1_M  (PCNT_FILTER_THRES_U1_V << PCNT_FILTER_THRES_U1_S)
+#define PCNT_FILTER_THRES_U1_V  0x000003ff
+#define PCNT_FILTER_THRES_U1_S  0
+
+/* PCNT_U1_CONF1_REG register
+ * Configuration register 1 for unit 1
+ */
+
+#define PCNT_U1_CONF1_REG (DR_REG_PCNT_BASE + 0x10)
+
+/* PCNT_CNT_THRES1_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES1_U1    0x0000ffff
+#define PCNT_CNT_THRES1_U1_M  (PCNT_CNT_THRES1_U1_V << PCNT_CNT_THRES1_U1_S)
+#define PCNT_CNT_THRES1_U1_V  0x0000ffff
+#define PCNT_CNT_THRES1_U1_S  16
+
+/* PCNT_CNT_THRES0_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES0_U1    0x0000ffff
+#define PCNT_CNT_THRES0_U1_M  (PCNT_CNT_THRES0_U1_V << PCNT_CNT_THRES0_U1_S)
+#define PCNT_CNT_THRES0_U1_V  0x0000ffff
+#define PCNT_CNT_THRES0_U1_S  0
+
+/* PCNT_U1_CONF2_REG register
+ * Configuration register 2 for unit 1
+ */
+
+#define PCNT_U1_CONF2_REG (DR_REG_PCNT_BASE + 0x14)
+
+/* PCNT_CNT_L_LIM_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 1.
+ */
+
+#define PCNT_CNT_L_LIM_U1    0x0000ffff
+#define PCNT_CNT_L_LIM_U1_M  (PCNT_CNT_L_LIM_U1_V << PCNT_CNT_L_LIM_U1_S)
+#define PCNT_CNT_L_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U1_S  16
+
+/* PCNT_CNT_H_LIM_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 1.
+ */
+
+#define PCNT_CNT_H_LIM_U1    0x0000ffff
+#define PCNT_CNT_H_LIM_U1_M  (PCNT_CNT_H_LIM_U1_V << PCNT_CNT_H_LIM_U1_S)
+#define PCNT_CNT_H_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U1_S  0
+
+/* PCNT_U2_CONF0_REG register
+ * Configuration register 0 for unit 2
+ */
+
+#define PCNT_U2_CONF0_REG (DR_REG_PCNT_BASE + 0x18)
+
+/* PCNT_CH1_LCTRL_MODE_U2 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_M  (PCNT_CH1_LCTRL_MODE_U2_V << PCNT_CH1_LCTRL_MODE_U2_S)
+#define PCNT_CH1_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U2 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_M  (PCNT_CH1_HCTRL_MODE_U2_V << PCNT_CH1_HCTRL_MODE_U2_S)
+#define PCNT_CH1_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_S  28
+
+/* PCNT_CH1_POS_MODE_U2 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U2    0x00000003
+#define PCNT_CH1_POS_MODE_U2_M  (PCNT_CH1_POS_MODE_U2_V << PCNT_CH1_POS_MODE_U2_S)
+#define PCNT_CH1_POS_MODE_U2_V  0x00000003
+#define PCNT_CH1_POS_MODE_U2_S  26
+
+/* PCNT_CH1_NEG_MODE_U2 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U2    0x00000003
+#define PCNT_CH1_NEG_MODE_U2_M  (PCNT_CH1_NEG_MODE_U2_V << PCNT_CH1_NEG_MODE_U2_S)
+#define PCNT_CH1_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U2_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U2 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_M  (PCNT_CH0_LCTRL_MODE_U2_V << PCNT_CH0_LCTRL_MODE_U2_S)
+#define PCNT_CH0_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U2 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_M  (PCNT_CH0_HCTRL_MODE_U2_V << PCNT_CH0_HCTRL_MODE_U2_S)
+#define PCNT_CH0_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_S  20
+
+/* PCNT_CH0_POS_MODE_U2 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U2    0x00000003
+#define PCNT_CH0_POS_MODE_U2_M  (PCNT_CH0_POS_MODE_U2_V << PCNT_CH0_POS_MODE_U2_S)
+#define PCNT_CH0_POS_MODE_U2_V  0x00000003
+#define PCNT_CH0_POS_MODE_U2_S  18
+
+/* PCNT_CH0_NEG_MODE_U2 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U2    0x00000003
+#define PCNT_CH0_NEG_MODE_U2_M  (PCNT_CH0_NEG_MODE_U2_V << PCNT_CH0_NEG_MODE_U2_S)
+#define PCNT_CH0_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U2_S  16
+
+/* PCNT_THR_THRES1_EN_U2 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 2's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U2    (BIT(15))
+#define PCNT_THR_THRES1_EN_U2_M  (PCNT_THR_THRES1_EN_U2_V << PCNT_THR_THRES1_EN_U2_S)
+#define PCNT_THR_THRES1_EN_U2_V  0x00000001
+#define PCNT_THR_THRES1_EN_U2_S  15
+
+/* PCNT_THR_THRES0_EN_U2 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 2's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U2    (BIT(14))
+#define PCNT_THR_THRES0_EN_U2_M  (PCNT_THR_THRES0_EN_U2_V << PCNT_THR_THRES0_EN_U2_S)
+#define PCNT_THR_THRES0_EN_U2_V  0x00000001
+#define PCNT_THR_THRES0_EN_U2_S  14
+
+/* PCNT_THR_L_LIM_EN_U2 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 2's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U2    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U2_M  (PCNT_THR_L_LIM_EN_U2_V << PCNT_THR_L_LIM_EN_U2_S)
+#define PCNT_THR_L_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U2_S  13
+
+/* PCNT_THR_H_LIM_EN_U2 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 2's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U2    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U2_M  (PCNT_THR_H_LIM_EN_U2_V << PCNT_THR_H_LIM_EN_U2_S)
+#define PCNT_THR_H_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U2_S  12
+
+/* PCNT_THR_ZERO_EN_U2 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 2's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U2    (BIT(11))
+#define PCNT_THR_ZERO_EN_U2_M  (PCNT_THR_ZERO_EN_U2_V << PCNT_THR_ZERO_EN_U2_S)
+#define PCNT_THR_ZERO_EN_U2_V  0x00000001
+#define PCNT_THR_ZERO_EN_U2_S  11
+
+/* PCNT_FILTER_EN_U2 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 2's input filter.
+ */
+
+#define PCNT_FILTER_EN_U2    (BIT(10))
+#define PCNT_FILTER_EN_U2_M  (PCNT_FILTER_EN_U2_V << PCNT_FILTER_EN_U2_S)
+#define PCNT_FILTER_EN_U2_V  0x00000001
+#define PCNT_FILTER_EN_U2_S  10
+
+/* PCNT_FILTER_THRES_U2 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U2    0x000003ff
+#define PCNT_FILTER_THRES_U2_M  (PCNT_FILTER_THRES_U2_V << PCNT_FILTER_THRES_U2_S)
+#define PCNT_FILTER_THRES_U2_V  0x000003ff
+#define PCNT_FILTER_THRES_U2_S  0
+
+/* PCNT_U2_CONF1_REG register
+ * Configuration register 1 for unit 2
+ */
+
+#define PCNT_U2_CONF1_REG (DR_REG_PCNT_BASE + 0x1c)
+
+/* PCNT_CNT_THRES1_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES1_U2    0x0000ffff
+#define PCNT_CNT_THRES1_U2_M  (PCNT_CNT_THRES1_U2_V << PCNT_CNT_THRES1_U2_S)
+#define PCNT_CNT_THRES1_U2_V  0x0000ffff
+#define PCNT_CNT_THRES1_U2_S  16
+
+/* PCNT_CNT_THRES0_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES0_U2    0x0000ffff
+#define PCNT_CNT_THRES0_U2_M  (PCNT_CNT_THRES0_U2_V << PCNT_CNT_THRES0_U2_S)
+#define PCNT_CNT_THRES0_U2_V  0x0000ffff
+#define PCNT_CNT_THRES0_U2_S  0
+
+/* PCNT_U2_CONF2_REG register
+ * Configuration register 2 for unit 2
+ */
+
+#define PCNT_U2_CONF2_REG (DR_REG_PCNT_BASE + 0x20)
+
+/* PCNT_CNT_L_LIM_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 2.
+ */
+
+#define PCNT_CNT_L_LIM_U2    0x0000ffff
+#define PCNT_CNT_L_LIM_U2_M  (PCNT_CNT_L_LIM_U2_V << PCNT_CNT_L_LIM_U2_S)
+#define PCNT_CNT_L_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U2_S  16
+
+/* PCNT_CNT_H_LIM_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 2.
+ */
+
+#define PCNT_CNT_H_LIM_U2    0x0000ffff
+#define PCNT_CNT_H_LIM_U2_M  (PCNT_CNT_H_LIM_U2_V << PCNT_CNT_H_LIM_U2_S)
+#define PCNT_CNT_H_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U2_S  0
+
+/* PCNT_U3_CONF0_REG register
+ * Configuration register 0 for unit 3
+ */
+
+#define PCNT_U3_CONF0_REG (DR_REG_PCNT_BASE + 0x24)
+
+/* PCNT_CH1_LCTRL_MODE_U3 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_M  (PCNT_CH1_LCTRL_MODE_U3_V << PCNT_CH1_LCTRL_MODE_U3_S)
+#define PCNT_CH1_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U3 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_M  (PCNT_CH1_HCTRL_MODE_U3_V << PCNT_CH1_HCTRL_MODE_U3_S)
+#define PCNT_CH1_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_S  28
+
+/* PCNT_CH1_POS_MODE_U3 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U3    0x00000003
+#define PCNT_CH1_POS_MODE_U3_M  (PCNT_CH1_POS_MODE_U3_V << PCNT_CH1_POS_MODE_U3_S)
+#define PCNT_CH1_POS_MODE_U3_V  0x00000003
+#define PCNT_CH1_POS_MODE_U3_S  26
+
+/* PCNT_CH1_NEG_MODE_U3 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U3    0x00000003
+#define PCNT_CH1_NEG_MODE_U3_M  (PCNT_CH1_NEG_MODE_U3_V << PCNT_CH1_NEG_MODE_U3_S)
+#define PCNT_CH1_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U3_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U3 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_M  (PCNT_CH0_LCTRL_MODE_U3_V << PCNT_CH0_LCTRL_MODE_U3_S)
+#define PCNT_CH0_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U3 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_M  (PCNT_CH0_HCTRL_MODE_U3_V << PCNT_CH0_HCTRL_MODE_U3_S)
+#define PCNT_CH0_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_S  20
+
+/* PCNT_CH0_POS_MODE_U3 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U3    0x00000003
+#define PCNT_CH0_POS_MODE_U3_M  (PCNT_CH0_POS_MODE_U3_V << PCNT_CH0_POS_MODE_U3_S)
+#define PCNT_CH0_POS_MODE_U3_V  0x00000003
+#define PCNT_CH0_POS_MODE_U3_S  18
+
+/* PCNT_CH0_NEG_MODE_U3 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U3    0x00000003
+#define PCNT_CH0_NEG_MODE_U3_M  (PCNT_CH0_NEG_MODE_U3_V << PCNT_CH0_NEG_MODE_U3_S)
+#define PCNT_CH0_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U3_S  16
+
+/* PCNT_THR_THRES1_EN_U3 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 3's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U3    (BIT(15))
+#define PCNT_THR_THRES1_EN_U3_M  (PCNT_THR_THRES1_EN_U3_V << PCNT_THR_THRES1_EN_U3_S)
+#define PCNT_THR_THRES1_EN_U3_V  0x00000001
+#define PCNT_THR_THRES1_EN_U3_S  15
+
+/* PCNT_THR_THRES0_EN_U3 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 3's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U3    (BIT(14))
+#define PCNT_THR_THRES0_EN_U3_M  (PCNT_THR_THRES0_EN_U3_V << PCNT_THR_THRES0_EN_U3_S)
+#define PCNT_THR_THRES0_EN_U3_V  0x00000001
+#define PCNT_THR_THRES0_EN_U3_S  14
+
+/* PCNT_THR_L_LIM_EN_U3 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 3's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U3    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U3_M  (PCNT_THR_L_LIM_EN_U3_V << PCNT_THR_L_LIM_EN_U3_S)
+#define PCNT_THR_L_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U3_S  13
+
+/* PCNT_THR_H_LIM_EN_U3 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 3's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U3    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U3_M  (PCNT_THR_H_LIM_EN_U3_V << PCNT_THR_H_LIM_EN_U3_S)
+#define PCNT_THR_H_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U3_S  12
+
+/* PCNT_THR_ZERO_EN_U3 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 3's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U3    (BIT(11))
+#define PCNT_THR_ZERO_EN_U3_M  (PCNT_THR_ZERO_EN_U3_V << PCNT_THR_ZERO_EN_U3_S)
+#define PCNT_THR_ZERO_EN_U3_V  0x00000001
+#define PCNT_THR_ZERO_EN_U3_S  11
+
+/* PCNT_FILTER_EN_U3 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 3's input filter.
+ */
+
+#define PCNT_FILTER_EN_U3    (BIT(10))
+#define PCNT_FILTER_EN_U3_M  (PCNT_FILTER_EN_U3_V << PCNT_FILTER_EN_U3_S)
+#define PCNT_FILTER_EN_U3_V  0x00000001
+#define PCNT_FILTER_EN_U3_S  10
+
+/* PCNT_FILTER_THRES_U3 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U3    0x000003ff
+#define PCNT_FILTER_THRES_U3_M  (PCNT_FILTER_THRES_U3_V << PCNT_FILTER_THRES_U3_S)
+#define PCNT_FILTER_THRES_U3_V  0x000003ff
+#define PCNT_FILTER_THRES_U3_S  0
+
+/* PCNT_U3_CONF1_REG register
+ * Configuration register 1 for unit 3
+ */
+
+#define PCNT_U3_CONF1_REG (DR_REG_PCNT_BASE + 0x28)
+
+/* PCNT_CNT_THRES1_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES1_U3    0x0000ffff
+#define PCNT_CNT_THRES1_U3_M  (PCNT_CNT_THRES1_U3_V << PCNT_CNT_THRES1_U3_S)
+#define PCNT_CNT_THRES1_U3_V  0x0000ffff
+#define PCNT_CNT_THRES1_U3_S  16
+
+/* PCNT_CNT_THRES0_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES0_U3    0x0000ffff
+#define PCNT_CNT_THRES0_U3_M  (PCNT_CNT_THRES0_U3_V << PCNT_CNT_THRES0_U3_S)
+#define PCNT_CNT_THRES0_U3_V  0x0000ffff
+#define PCNT_CNT_THRES0_U3_S  0
+
+/* PCNT_U3_CONF2_REG register
+ * Configuration register 2 for unit 3
+ */
+
+#define PCNT_U3_CONF2_REG (DR_REG_PCNT_BASE + 0x2c)
+
+/* PCNT_CNT_L_LIM_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 3.
+ */
+
+#define PCNT_CNT_L_LIM_U3    0x0000ffff
+#define PCNT_CNT_L_LIM_U3_M  (PCNT_CNT_L_LIM_U3_V << PCNT_CNT_L_LIM_U3_S)
+#define PCNT_CNT_L_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U3_S  16
+
+/* PCNT_CNT_H_LIM_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 3.
+ */
+
+#define PCNT_CNT_H_LIM_U3    0x0000ffff
+#define PCNT_CNT_H_LIM_U3_M  (PCNT_CNT_H_LIM_U3_V << PCNT_CNT_H_LIM_U3_S)
+#define PCNT_CNT_H_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U3_S  0
+
+#define PCNT_U4_CONF0_REG          (DR_REG_PCNT_BASE + 0x0030)
+
+/* PCNT_CH1_LCTRL_MODE_U4 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U4_M  ((PCNT_CH1_LCTRL_MODE_U4_V)<<(PCNT_CH1_LCTRL_MODE_U4_S))
+#define PCNT_CH1_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U4_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U4 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U4_M  ((PCNT_CH1_HCTRL_MODE_U4_V)<<(PCNT_CH1_HCTRL_MODE_U4_S))
+#define PCNT_CH1_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U4_S  28
+
+/* PCNT_CH1_POS_MODE_U4 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U4  0x00000003
+#define PCNT_CH1_POS_MODE_U4_M  ((PCNT_CH1_POS_MODE_U4_V)<<(PCNT_CH1_POS_MODE_U4_S))
+#define PCNT_CH1_POS_MODE_U4_V  0x3
+#define PCNT_CH1_POS_MODE_U4_S  26
+
+/* PCNT_CH1_NEG_MODE_U4 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U4  0x00000003
+#define PCNT_CH1_NEG_MODE_U4_M  ((PCNT_CH1_NEG_MODE_U4_V)<<(PCNT_CH1_NEG_MODE_U4_S))
+#define PCNT_CH1_NEG_MODE_U4_V  0x3
+#define PCNT_CH1_NEG_MODE_U4_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U4 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U4_M  ((PCNT_CH0_LCTRL_MODE_U4_V)<<(PCNT_CH0_LCTRL_MODE_U4_S))
+#define PCNT_CH0_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U4_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U4 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U4_M  ((PCNT_CH0_HCTRL_MODE_U4_V)<<(PCNT_CH0_HCTRL_MODE_U4_S))
+#define PCNT_CH0_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U4_S  20
+
+/* PCNT_CH0_POS_MODE_U4 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U4  0x00000003
+#define PCNT_CH0_POS_MODE_U4_M  ((PCNT_CH0_POS_MODE_U4_V)<<(PCNT_CH0_POS_MODE_U4_S))
+#define PCNT_CH0_POS_MODE_U4_V  0x3
+#define PCNT_CH0_POS_MODE_U4_S  18
+
+/* PCNT_CH0_NEG_MODE_U4 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U4  0x00000003
+#define PCNT_CH0_NEG_MODE_U4_M  ((PCNT_CH0_NEG_MODE_U4_V)<<(PCNT_CH0_NEG_MODE_U4_S))
+#define PCNT_CH0_NEG_MODE_U4_V  0x3
+#define PCNT_CH0_NEG_MODE_U4_S  16
+
+/* PCNT_THR_THRES1_EN_U4 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U4  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_V  0x1
+#define PCNT_THR_THRES1_EN_U4_S  15
+
+/* PCNT_THR_THRES0_EN_U4 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U4  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_V  0x1
+#define PCNT_THR_THRES0_EN_U4_S  14
+
+/* PCNT_THR_L_LIM_EN_U4 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_l_lim  value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U4  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_V  0x1
+#define PCNT_THR_L_LIM_EN_U4_S  13
+
+/* PCNT_THR_H_LIM_EN_U4 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U4  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_V  0x1
+#define PCNT_THR_H_LIM_EN_U4_S  12
+
+/* PCNT_THR_ZERO_EN_U4 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U4  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_V  0x1
+#define PCNT_THR_ZERO_EN_U4_S  11
+
+/* PCNT_FILTER_EN_U4 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit4.
+ */
+
+#define PCNT_FILTER_EN_U4  (BIT(10))
+#define PCNT_FILTER_EN_U4_M  (BIT(10))
+#define PCNT_FILTER_EN_U4_V  0x1
+#define PCNT_FILTER_EN_U4_S  10
+
+/* PCNT_FILTER_THRES_U4 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit4.
+ */
+
+#define PCNT_FILTER_THRES_U4  0x000003FF
+#define PCNT_FILTER_THRES_U4_M  ((PCNT_FILTER_THRES_U4_V)<<(PCNT_FILTER_THRES_U4_S))
+#define PCNT_FILTER_THRES_U4_V  0x3FF
+#define PCNT_FILTER_THRES_U4_S  0
+
+#define PCNT_U4_CONF1_REG          (DR_REG_PCNT_BASE + 0x0034)
+
+/* PCNT_CNT_THRES1_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure thres1 value for unit4.
+ */
+
+#define PCNT_CNT_THRES1_U4  0x0000FFFF
+#define PCNT_CNT_THRES1_U4_M  ((PCNT_CNT_THRES1_U4_V)<<(PCNT_CNT_THRES1_U4_S))
+#define PCNT_CNT_THRES1_U4_V  0xFFFF
+#define PCNT_CNT_THRES1_U4_S  16
+
+/* PCNT_CNT_THRES0_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit4.
+ */
+
+#define PCNT_CNT_THRES0_U4  0x0000FFFF
+#define PCNT_CNT_THRES0_U4_M  ((PCNT_CNT_THRES0_U4_V)<<(PCNT_CNT_THRES0_U4_S))
+#define PCNT_CNT_THRES0_U4_V  0xFFFF
+#define PCNT_CNT_THRES0_U4_S  0
+
+#define PCNT_U4_CONF2_REG          (DR_REG_PCNT_BASE + 0x0038)
+
+/* PCNT_CNT_L_LIM_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit4.
+ */
+
+#define PCNT_CNT_L_LIM_U4  0x0000FFFF
+#define PCNT_CNT_L_LIM_U4_M  ((PCNT_CNT_L_LIM_U4_V)<<(PCNT_CNT_L_LIM_U4_S))
+#define PCNT_CNT_L_LIM_U4_V  0xFFFF
+#define PCNT_CNT_L_LIM_U4_S  16
+
+/* PCNT_CNT_H_LIM_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit4.
+ */
+
+#define PCNT_CNT_H_LIM_U4  0x0000FFFF
+#define PCNT_CNT_H_LIM_U4_M  ((PCNT_CNT_H_LIM_U4_V)<<(PCNT_CNT_H_LIM_U4_S))
+#define PCNT_CNT_H_LIM_U4_V  0xFFFF
+#define PCNT_CNT_H_LIM_U4_S  0
+
+#define PCNT_U5_CONF0_REG          (DR_REG_PCNT_BASE + 0x003c)
+
+/* PCNT_CH1_LCTRL_MODE_U5 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U5_M  ((PCNT_CH1_LCTRL_MODE_U5_V)<<(PCNT_CH1_LCTRL_MODE_U5_S))
+#define PCNT_CH1_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U5_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U5 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U5_M  ((PCNT_CH1_HCTRL_MODE_U5_V)<<(PCNT_CH1_HCTRL_MODE_U5_S))
+#define PCNT_CH1_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U5_S  28
+
+/* PCNT_CH1_POS_MODE_U5 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U5  0x00000003
+#define PCNT_CH1_POS_MODE_U5_M  ((PCNT_CH1_POS_MODE_U5_V)<<(PCNT_CH1_POS_MODE_U5_S))
+#define PCNT_CH1_POS_MODE_U5_V  0x3
+#define PCNT_CH1_POS_MODE_U5_S  26
+
+/* PCNT_CH1_NEG_MODE_U5 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U5  0x00000003
+#define PCNT_CH1_NEG_MODE_U5_M  ((PCNT_CH1_NEG_MODE_U5_V)<<(PCNT_CH1_NEG_MODE_U5_S))
+#define PCNT_CH1_NEG_MODE_U5_V  0x3
+#define PCNT_CH1_NEG_MODE_U5_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U5 : R/W ;bitpos:[23:22] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U5_M  ((PCNT_CH0_LCTRL_MODE_U5_V)<<(PCNT_CH0_LCTRL_MODE_U5_S))
+#define PCNT_CH0_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U5_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U5 : R/W ;bitpos:[21:20] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's high
+ * control signal for unit5.
+ * 0:increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U5_M  ((PCNT_CH0_HCTRL_MODE_U5_V)<<(PCNT_CH0_HCTRL_MODE_U5_S))
+#define PCNT_CH0_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U5_S  20
+
+/* PCNT_CH0_POS_MODE_U5 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U5  0x00000003
+#define PCNT_CH0_POS_MODE_U5_M  ((PCNT_CH0_POS_MODE_U5_V)<<(PCNT_CH0_POS_MODE_U5_S))
+#define PCNT_CH0_POS_MODE_U5_V  0x3
+#define PCNT_CH0_POS_MODE_U5_S  18
+
+/* PCNT_CH0_NEG_MODE_U5 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U5  0x00000003
+#define PCNT_CH0_NEG_MODE_U5_M  ((PCNT_CH0_NEG_MODE_U5_V)<<(PCNT_CH0_NEG_MODE_U5_S))
+#define PCNT_CH0_NEG_MODE_U5_V  0x3
+#define PCNT_CH0_NEG_MODE_U5_S  16
+
+/* PCNT_THR_THRES1_EN_U5 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U5  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_V  0x1
+#define PCNT_THR_THRES1_EN_U5_S  15
+
+/* PCNT_THR_THRES0_EN_U5 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U5  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_V  0x1
+#define PCNT_THR_THRES0_EN_U5_S  14
+
+/* PCNT_THR_L_LIM_EN_U5 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U5  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_V  0x1
+#define PCNT_THR_L_LIM_EN_U5_S  13
+
+/* PCNT_THR_H_LIM_EN_U5 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U5  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_V  0x1
+#define PCNT_THR_H_LIM_EN_U5_S  12
+
+/* PCNT_THR_ZERO_EN_U5 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U5  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_V  0x1
+#define PCNT_THR_ZERO_EN_U5_S  11
+
+/* PCNT_FILTER_EN_U5 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit5.
+ */
+
+#define PCNT_FILTER_EN_U5  (BIT(10))
+#define PCNT_FILTER_EN_U5_M  (BIT(10))
+#define PCNT_FILTER_EN_U5_V  0x1
+#define PCNT_FILTER_EN_U5_S  10
+
+/* PCNT_FILTER_THRES_U5 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit5.
+ */
+
+#define PCNT_FILTER_THRES_U5  0x000003FF
+#define PCNT_FILTER_THRES_U5_M  ((PCNT_FILTER_THRES_U5_V)<<(PCNT_FILTER_THRES_U5_S))
+#define PCNT_FILTER_THRES_U5_V  0x3FF
+#define PCNT_FILTER_THRES_U5_S  0
+
+#define PCNT_U5_CONF1_REG          (DR_REG_PCNT_BASE + 0x0040)
+
+/* PCNT_CNT_THRES1_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit5.
+ */
+
+#define PCNT_CNT_THRES1_U5  0x0000FFFF
+#define PCNT_CNT_THRES1_U5_M  ((PCNT_CNT_THRES1_U5_V)<<(PCNT_CNT_THRES1_U5_S))
+#define PCNT_CNT_THRES1_U5_V  0xFFFF
+#define PCNT_CNT_THRES1_U5_S  16
+
+/* PCNT_CNT_THRES0_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit5.
+ */
+
+#define PCNT_CNT_THRES0_U5  0x0000FFFF
+#define PCNT_CNT_THRES0_U5_M  ((PCNT_CNT_THRES0_U5_V)<<(PCNT_CNT_THRES0_U5_S))
+#define PCNT_CNT_THRES0_U5_V  0xFFFF
+#define PCNT_CNT_THRES0_U5_S  0
+
+#define PCNT_U5_CONF2_REG          (DR_REG_PCNT_BASE + 0x0044)
+
+/* PCNT_CNT_L_LIM_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit5.
+ */
+
+#define PCNT_CNT_L_LIM_U5  0x0000FFFF
+#define PCNT_CNT_L_LIM_U5_M  ((PCNT_CNT_L_LIM_U5_V)<<(PCNT_CNT_L_LIM_U5_S))
+#define PCNT_CNT_L_LIM_U5_V  0xFFFF
+#define PCNT_CNT_L_LIM_U5_S  16
+
+/* PCNT_CNT_H_LIM_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit5.
+ */
+
+#define PCNT_CNT_H_LIM_U5  0x0000FFFF
+#define PCNT_CNT_H_LIM_U5_M  ((PCNT_CNT_H_LIM_U5_V)<<(PCNT_CNT_H_LIM_U5_S))
+#define PCNT_CNT_H_LIM_U5_V  0xFFFF
+#define PCNT_CNT_H_LIM_U5_S  0
+
+#define PCNT_U6_CONF0_REG          (DR_REG_PCNT_BASE + 0x0048)
+
+/* PCNT_CH1_LCTRL_MODE_U6 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * low control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U6_M  ((PCNT_CH1_LCTRL_MODE_U6_V)<<(PCNT_CH1_LCTRL_MODE_U6_S))
+#define PCNT_CH1_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U6_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U6 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U6_M  ((PCNT_CH1_HCTRL_MODE_U6_V)<<(PCNT_CH1_HCTRL_MODE_U6_S))
+#define PCNT_CH1_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U6_S  28
+
+/* PCNT_CH1_POS_MODE_U6 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U6  0x00000003
+#define PCNT_CH1_POS_MODE_U6_M  ((PCNT_CH1_POS_MODE_U6_V)<<(PCNT_CH1_POS_MODE_U6_S))
+#define PCNT_CH1_POS_MODE_U6_V  0x3
+#define PCNT_CH1_POS_MODE_U6_S  26
+
+/* PCNT_CH1_NEG_MODE_U6 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * input negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U6  0x00000003
+#define PCNT_CH1_NEG_MODE_U6_M  ((PCNT_CH1_NEG_MODE_U6_V)<<(PCNT_CH1_NEG_MODE_U6_S))
+#define PCNT_CH1_NEG_MODE_U6_V  0x3
+#define PCNT_CH1_NEG_MODE_U6_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U6 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U6_M  ((PCNT_CH0_LCTRL_MODE_U6_V)<<(PCNT_CH0_LCTRL_MODE_U6_S))
+#define PCNT_CH0_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U6_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U6 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * high control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U6_M  ((PCNT_CH0_HCTRL_MODE_U6_V)<<(PCNT_CH0_HCTRL_MODE_U6_S))
+#define PCNT_CH0_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U6_S  20
+
+/* PCNT_CH0_POS_MODE_U6 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U6  0x00000003
+#define PCNT_CH0_POS_MODE_U6_M  ((PCNT_CH0_POS_MODE_U6_V)<<(PCNT_CH0_POS_MODE_U6_S))
+#define PCNT_CH0_POS_MODE_U6_V  0x3
+#define PCNT_CH0_POS_MODE_U6_S  18
+
+/* PCNT_CH0_NEG_MODE_U6 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U6  0x00000003
+#define PCNT_CH0_NEG_MODE_U6_M  ((PCNT_CH0_NEG_MODE_U6_V)<<(PCNT_CH0_NEG_MODE_U6_S))
+#define PCNT_CH0_NEG_MODE_U6_V  0x3
+#define PCNT_CH0_NEG_MODE_U6_S  16
+
+/* PCNT_THR_THRES1_EN_U6 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit6's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U6  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_V  0x1
+#define PCNT_THR_THRES1_EN_U6_S  15
+
+/* PCNT_THR_THRES0_EN_U6 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U6  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_V  0x1
+#define PCNT_THR_THRES0_EN_U6_S  14
+
+/* PCNT_THR_L_LIM_EN_U6 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U6  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_V  0x1
+#define PCNT_THR_L_LIM_EN_U6_S  13
+
+/* PCNT_THR_H_LIM_EN_U6 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit6's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U6  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_V  0x1
+#define PCNT_THR_H_LIM_EN_U6_S  12
+
+/* PCNT_THR_ZERO_EN_U6 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U6  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_V  0x1
+#define PCNT_THR_ZERO_EN_U6_S  11
+
+/* PCNT_FILTER_EN_U6 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit6.
+ */
+
+#define PCNT_FILTER_EN_U6  (BIT(10))
+#define PCNT_FILTER_EN_U6_M  (BIT(10))
+#define PCNT_FILTER_EN_U6_V  0x1
+#define PCNT_FILTER_EN_U6_S  10
+
+/* PCNT_FILTER_THRES_U6 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is
+ * smaller than this value for unit6.
+ */
+
+#define PCNT_FILTER_THRES_U6  0x000003FF
+#define PCNT_FILTER_THRES_U6_M  ((PCNT_FILTER_THRES_U6_V)<<(PCNT_FILTER_THRES_U6_S))
+#define PCNT_FILTER_THRES_U6_V  0x3FF
+#define PCNT_FILTER_THRES_U6_S  0
+
+#define PCNT_U6_CONF1_REG          (DR_REG_PCNT_BASE + 0x004c)
+
+/* PCNT_CNT_THRES1_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit6.
+ */
+
+#define PCNT_CNT_THRES1_U6  0x0000FFFF
+#define PCNT_CNT_THRES1_U6_M  ((PCNT_CNT_THRES1_U6_V)<<(PCNT_CNT_THRES1_U6_S))
+#define PCNT_CNT_THRES1_U6_V  0xFFFF
+#define PCNT_CNT_THRES1_U6_S  16
+
+/* PCNT_CNT_THRES0_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit6.
+ */
+
+#define PCNT_CNT_THRES0_U6  0x0000FFFF
+#define PCNT_CNT_THRES0_U6_M  ((PCNT_CNT_THRES0_U6_V)<<(PCNT_CNT_THRES0_U6_S))
+#define PCNT_CNT_THRES0_U6_V  0xFFFF
+#define PCNT_CNT_THRES0_U6_S  0
+
+#define PCNT_U6_CONF2_REG          (DR_REG_PCNT_BASE + 0x0050)
+
+/* PCNT_CNT_L_LIM_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit6.
+ */
+
+#define PCNT_CNT_L_LIM_U6  0x0000FFFF
+#define PCNT_CNT_L_LIM_U6_M  ((PCNT_CNT_L_LIM_U6_V)<<(PCNT_CNT_L_LIM_U6_S))
+#define PCNT_CNT_L_LIM_U6_V  0xFFFF
+#define PCNT_CNT_L_LIM_U6_S  16
+
+/* PCNT_CNT_H_LIM_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit6.
+ */
+
+#define PCNT_CNT_H_LIM_U6  0x0000FFFF
+#define PCNT_CNT_H_LIM_U6_M  ((PCNT_CNT_H_LIM_U6_V)<<(PCNT_CNT_H_LIM_U6_S))
+#define PCNT_CNT_H_LIM_U6_V  0xFFFF
+#define PCNT_CNT_H_LIM_U6_S  0
+
+#define PCNT_U7_CONF0_REG          (DR_REG_PCNT_BASE + 0x0054)
+
+/* PCNT_CH1_LCTRL_MODE_U7 : R/W ;bitpos:[31:30] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U7_M  ((PCNT_CH1_LCTRL_MODE_U7_V)<<(PCNT_CH1_LCTRL_MODE_U7_S))
+#define PCNT_CH1_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U7_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U7 : R/W ;bitpos:[29:28] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U7_M  ((PCNT_CH1_HCTRL_MODE_U7_V)<<(PCNT_CH1_HCTRL_MODE_U7_S))
+#define PCNT_CH1_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U7_S  28
+
+/* PCNT_CH1_POS_MODE_U7 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2:decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U7  0x00000003
+#define PCNT_CH1_POS_MODE_U7_M  ((PCNT_CH1_POS_MODE_U7_V)<<(PCNT_CH1_POS_MODE_U7_S))
+#define PCNT_CH1_POS_MODE_U7_V  0x3
+#define PCNT_CH1_POS_MODE_U7_S  26
+
+/* PCNT_CH1_NEG_MODE_U7 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U7  0x00000003
+#define PCNT_CH1_NEG_MODE_U7_M  ((PCNT_CH1_NEG_MODE_U7_V)<<(PCNT_CH1_NEG_MODE_U7_S))
+#define PCNT_CH1_NEG_MODE_U7_V  0x3
+#define PCNT_CH1_NEG_MODE_U7_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U7 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U7_M  ((PCNT_CH0_LCTRL_MODE_U7_V)<<(PCNT_CH0_LCTRL_MODE_U7_S))
+#define PCNT_CH0_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U7_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U7 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U7_M  ((PCNT_CH0_HCTRL_MODE_U7_V)<<(PCNT_CH0_HCTRL_MODE_U7_S))
+#define PCNT_CH0_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U7_S  20
+
+/* PCNT_CH0_POS_MODE_U7 : R/W ;bitpos:[19:18] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U7  0x00000003
+#define PCNT_CH0_POS_MODE_U7_M  ((PCNT_CH0_POS_MODE_U7_V)<<(PCNT_CH0_POS_MODE_U7_S))
+#define PCNT_CH0_POS_MODE_U7_V  0x3
+#define PCNT_CH0_POS_MODE_U7_S  18
+
+/* PCNT_CH0_NEG_MODE_U7 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * input negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U7  0x00000003
+#define PCNT_CH0_NEG_MODE_U7_M  ((PCNT_CH0_NEG_MODE_U7_V)<<(PCNT_CH0_NEG_MODE_U7_S))
+#define PCNT_CH0_NEG_MODE_U7_V  0x3
+#define PCNT_CH0_NEG_MODE_U7_S  16
+
+/* PCNT_THR_THRES1_EN_U7 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit7's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U7  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_V  0x1
+#define PCNT_THR_THRES1_EN_U7_S  15
+
+/* PCNT_THR_THRES0_EN_U7 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U7  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_V  0x1
+#define PCNT_THR_THRES0_EN_U7_S  14
+
+/* PCNT_THR_L_LIM_EN_U7 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U7  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_V  0x1
+#define PCNT_THR_L_LIM_EN_U7_S  13
+
+/* PCNT_THR_H_LIM_EN_U7 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit7's count
+ * with thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U7  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_V  0x1
+#define PCNT_THR_H_LIM_EN_U7_S  12
+
+/* PCNT_THR_ZERO_EN_U7 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U7  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_V  0x1
+#define PCNT_THR_ZERO_EN_U7_S  11
+
+/* PCNT_FILTER_EN_U7 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit7.
+ */
+
+#define PCNT_FILTER_EN_U7  (BIT(10))
+#define PCNT_FILTER_EN_U7_M  (BIT(10))
+#define PCNT_FILTER_EN_U7_V  0x1
+#define PCNT_FILTER_EN_U7_S  10
+
+/* PCNT_FILTER_THRES_U7 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit7.
+ */
+
+#define PCNT_FILTER_THRES_U7  0x000003FF
+#define PCNT_FILTER_THRES_U7_M  ((PCNT_FILTER_THRES_U7_V)<<(PCNT_FILTER_THRES_U7_S))
+#define PCNT_FILTER_THRES_U7_V  0x3FF
+#define PCNT_FILTER_THRES_U7_S  0
+
+#define PCNT_U7_CONF1_REG          (DR_REG_PCNT_BASE + 0x0058)
+
+/* PCNT_CNT_THRES1_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit7.
+ */
+
+#define PCNT_CNT_THRES1_U7  0x0000FFFF
+#define PCNT_CNT_THRES1_U7_M  ((PCNT_CNT_THRES1_U7_V)<<(PCNT_CNT_THRES1_U7_S))
+#define PCNT_CNT_THRES1_U7_V  0xFFFF
+#define PCNT_CNT_THRES1_U7_S  16
+
+/* PCNT_CNT_THRES0_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit7.
+ */
+
+#define PCNT_CNT_THRES0_U7  0x0000FFFF
+#define PCNT_CNT_THRES0_U7_M  ((PCNT_CNT_THRES0_U7_V)<<(PCNT_CNT_THRES0_U7_S))
+#define PCNT_CNT_THRES0_U7_V  0xFFFF
+#define PCNT_CNT_THRES0_U7_S  0
+
+#define PCNT_U7_CONF2_REG          (DR_REG_PCNT_BASE + 0x005c)
+
+/* PCNT_CNT_L_LIM_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit7.
+ */
+
+#define PCNT_CNT_L_LIM_U7  0x0000FFFF
+#define PCNT_CNT_L_LIM_U7_M  ((PCNT_CNT_L_LIM_U7_V)<<(PCNT_CNT_L_LIM_U7_S))
+#define PCNT_CNT_L_LIM_U7_V  0xFFFF
+#define PCNT_CNT_L_LIM_U7_S  16
+
+/* PCNT_CNT_H_LIM_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit7.
+ */
+
+#define PCNT_CNT_H_LIM_U7  0x0000FFFF
+#define PCNT_CNT_H_LIM_U7_M  ((PCNT_CNT_H_LIM_U7_V)<<(PCNT_CNT_H_LIM_U7_S))
+#define PCNT_CNT_H_LIM_U7_V  0xFFFF
+#define PCNT_CNT_H_LIM_U7_S  0
+
+#define PCNT_U0_CNT_REG          (DR_REG_PCNT_BASE + 0x0060)
+
+/* PCNT_PLUS_CNT_U0 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit0.
+ */
+
+#define PCNT_PLUS_CNT_U0  0x0000FFFF
+#define PCNT_PLUS_CNT_U0_M  ((PCNT_PLUS_CNT_U0_V)<<(PCNT_PLUS_CNT_U0_S))
+#define PCNT_PLUS_CNT_U0_V  0xFFFF
+#define PCNT_PLUS_CNT_U0_S  0
+
+#define PCNT_U1_CNT_REG          (DR_REG_PCNT_BASE + 0x0064)
+
+/* PCNT_PLUS_CNT_U1 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit1.
+ */
+
+#define PCNT_PLUS_CNT_U1  0x0000FFFF
+#define PCNT_PLUS_CNT_U1_M  ((PCNT_PLUS_CNT_U1_V)<<(PCNT_PLUS_CNT_U1_S))
+#define PCNT_PLUS_CNT_U1_V  0xFFFF
+#define PCNT_PLUS_CNT_U1_S  0
+
+#define PCNT_U2_CNT_REG          (DR_REG_PCNT_BASE + 0x0068)
+
+/* PCNT_PLUS_CNT_U2 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit2.
+ */
+
+#define PCNT_PLUS_CNT_U2  0x0000FFFF
+#define PCNT_PLUS_CNT_U2_M  ((PCNT_PLUS_CNT_U2_V)<<(PCNT_PLUS_CNT_U2_S))
+#define PCNT_PLUS_CNT_U2_V  0xFFFF
+#define PCNT_PLUS_CNT_U2_S  0
+
+#define PCNT_U3_CNT_REG          (DR_REG_PCNT_BASE + 0x006c)
+
+/* PCNT_PLUS_CNT_U3 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit3.
+ */
+
+#define PCNT_PLUS_CNT_U3  0x0000FFFF
+#define PCNT_PLUS_CNT_U3_M  ((PCNT_PLUS_CNT_U3_V)<<(PCNT_PLUS_CNT_U3_S))
+#define PCNT_PLUS_CNT_U3_V  0xFFFF
+#define PCNT_PLUS_CNT_U3_S  0
+
+#define PCNT_U4_CNT_REG          (DR_REG_PCNT_BASE + 0x0070)
+
+/* PCNT_PLUS_CNT_U4 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit4.
+ */
+
+#define PCNT_PLUS_CNT_U4  0x0000FFFF
+#define PCNT_PLUS_CNT_U4_M  ((PCNT_PLUS_CNT_U4_V)<<(PCNT_PLUS_CNT_U4_S))
+#define PCNT_PLUS_CNT_U4_V  0xFFFF
+#define PCNT_PLUS_CNT_U4_S  0
+
+#define PCNT_U5_CNT_REG          (DR_REG_PCNT_BASE + 0x0074)
+
+/* PCNT_PLUS_CNT_U5 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit5.
+ */
+
+#define PCNT_PLUS_CNT_U5  0x0000FFFF
+#define PCNT_PLUS_CNT_U5_M  ((PCNT_PLUS_CNT_U5_V)<<(PCNT_PLUS_CNT_U5_S))
+#define PCNT_PLUS_CNT_U5_V  0xFFFF
+#define PCNT_PLUS_CNT_U5_S  0
+
+#define PCNT_U6_CNT_REG          (DR_REG_PCNT_BASE + 0x0078)
+
+/* PCNT_PLUS_CNT_U6 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit6.
+ */
+
+#define PCNT_PLUS_CNT_U6  0x0000FFFF
+#define PCNT_PLUS_CNT_U6_M  ((PCNT_PLUS_CNT_U6_V)<<(PCNT_PLUS_CNT_U6_S))
+#define PCNT_PLUS_CNT_U6_V  0xFFFF
+#define PCNT_PLUS_CNT_U6_S  0
+
+#define PCNT_U7_CNT_REG          (DR_REG_PCNT_BASE + 0x007c)
+
+/* PCNT_PLUS_CNT_U7 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit7.
+ */
+
+#define PCNT_PLUS_CNT_U7  0x0000FFFF
+#define PCNT_PLUS_CNT_U7_M  ((PCNT_PLUS_CNT_U7_V)<<(PCNT_PLUS_CNT_U7_S))
+#define PCNT_PLUS_CNT_U7_V  0xFFFF
+#define PCNT_PLUS_CNT_U7_S  0
+
+#define PCNT_INT_RAW_REG          (DR_REG_PCNT_BASE + 0x0080)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_RAW : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_RAW : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_RAW : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_RAW : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_RAW : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_RAW : RO ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_RAW : RO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_RAW : RO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_S  0
+
+#define PCNT_INT_ST_REG          (DR_REG_PCNT_BASE + 0x0084)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ST : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ST  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ST : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ST  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ST : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ST  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ST  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ST : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ST  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ST : RO; bitpos: [2]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U2_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ST    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_M  (PCNT_CNT_THR_EVENT_U2_INT_ST_V << PCNT_CNT_THR_EVENT_U2_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ST : RO; bitpos: [1]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U1_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ST    (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_M  (PCNT_CNT_THR_EVENT_U1_INT_ST_V << PCNT_CNT_THR_EVENT_U1_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ST : RO; bitpos: [0]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U0_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ST    (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_M  (PCNT_CNT_THR_EVENT_U0_INT_ST_V << PCNT_CNT_THR_EVENT_U0_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_S  0
+
+/* PCNT_INT_ENA_REG register
+ * Interrupt enable register
+ */
+
+#define PCNT_INT_ENA_REG          (DR_REG_PCNT_BASE + 0x0088)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ENA : R/W ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ENA : R/W ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ENA : R/W ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ENA : R/W ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ENA : R/W ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ENA : R/W ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_S  0
+
+#define PCNT_INT_CLR_REG          (DR_REG_PCNT_BASE + 0x008c)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_CLR : WO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel7 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_CLR : WO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel6 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_CLR : WO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel5 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_CLR : WO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel4 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_CLR : WO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel3 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_CLR : WO; bitpos: [2]; default: 0;
+ * Set this bit to clear the PCNT_CNT_THR_EVENT_U2_INT interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_M  (PCNT_CNT_THR_EVENT_U2_INT_CLR_V << PCNT_CNT_THR_EVENT_U2_INT_CLR_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_CLR : WO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel1 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_CLR : WO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel0 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_S  0
+
+#define PCNT_U0_STATUS_REG          (DR_REG_PCNT_BASE + 0x0090)
+
+/* PCNT_CORE_STATUS_U0 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U0  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_M  ((PCNT_CORE_STATUS_U0_V)<<(PCNT_CORE_STATUS_U0_S))
+#define PCNT_CORE_STATUS_U0_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_S  0
+
+/* 0: positive value to zero;
+ * 1: negative value to zero;
+ * 2: counter value negative;
+ * 3: counter value positive
+ */
+
+#define PCNT_STATUS_CNT_MODE    0x3
+#define PCNT_STATUS_CNT_MODE_M  ((PCNT_STATUS_CNT_MODE_V)<<(PCNT_STATUS_CNT_MODE_S))
+#define PCNT_STATUS_CNT_MODE_V  0x3
+#define PCNT_STATUS_CNT_MODE_S  0
+
+/* counter value equals to thresh1 */
+
+#define PCNT_STATUS_THRES1    BIT(2)
+#define PCNT_STATUS_THRES1_M  BIT(2)
+#define PCNT_STATUS_THRES1_V  0x1
+#define PCNT_STATUS_THRES1_S  2
+
+/* counter value equals to thresh0 */
+
+#define PCNT_STATUS_THRES0    BIT(3)
+#define PCNT_STATUS_THRES0_M  BIT(3)
+#define PCNT_STATUS_THRES0_V  0x1
+#define PCNT_STATUS_THRES0_S  3
+
+/* counter value reaches h_lim */
+
+#define PCNT_STATUS_L_LIM    BIT(4)
+#define PCNT_STATUS_L_LIM_M  BIT(4)
+#define PCNT_STATUS_L_LIM_V  0x1
+#define PCNT_STATUS_L_LIM_S  4
+
+/* counter value reaches l_lim */
+
+#define PCNT_STATUS_H_LIM    BIT(5)
+#define PCNT_STATUS_H_LIM_M  BIT(5)
+#define PCNT_STATUS_H_LIM_V  0x1
+#define PCNT_STATUS_H_LIM_S  5
+
+/* counter value equals to zero */
+
+#define PCNT_STATUS_ZERO    BIT(6)
+#define PCNT_STATUS_ZERO_M  BIT(6)
+#define PCNT_STATUS_ZERO_V  0x1
+#define PCNT_STATUS_ZERO_S  6
+
+#define PCNT_U1_STATUS_REG          (DR_REG_PCNT_BASE + 0x0094)
+
+/* PCNT_CORE_STATUS_U1 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U1  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_M  ((PCNT_CORE_STATUS_U1_V)<<(PCNT_CORE_STATUS_U1_S))
+#define PCNT_CORE_STATUS_U1_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_S  0
+
+#define PCNT_U2_STATUS_REG          (DR_REG_PCNT_BASE + 0x0098)
+
+/* PCNT_CORE_STATUS_U2 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U2  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_M  ((PCNT_CORE_STATUS_U2_V)<<(PCNT_CORE_STATUS_U2_S))
+#define PCNT_CORE_STATUS_U2_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_S  0
+
+#define PCNT_U3_STATUS_REG          (DR_REG_PCNT_BASE + 0x009c)
+
+/* PCNT_CORE_STATUS_U3 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U3  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_M  ((PCNT_CORE_STATUS_U3_V)<<(PCNT_CORE_STATUS_U3_S))
+#define PCNT_CORE_STATUS_U3_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_S  0
+
+#define PCNT_U4_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a0)
+/* PCNT_CORE_STATUS_U4 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U4  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_M  ((PCNT_CORE_STATUS_U4_V)<<(PCNT_CORE_STATUS_U4_S))
+#define PCNT_CORE_STATUS_U4_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_S  0
+
+#define PCNT_U5_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a4)
+/* PCNT_CORE_STATUS_U5 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U5  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_M  ((PCNT_CORE_STATUS_U5_V)<<(PCNT_CORE_STATUS_U5_S))
+#define PCNT_CORE_STATUS_U5_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_S  0
+
+#define PCNT_U6_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a8)
+/* PCNT_CORE_STATUS_U6 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U6  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_M  ((PCNT_CORE_STATUS_U6_V)<<(PCNT_CORE_STATUS_U6_S))
+#define PCNT_CORE_STATUS_U6_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_S  0
+
+#define PCNT_U7_STATUS_REG          (DR_REG_PCNT_BASE + 0x00ac)
+
+/* PCNT_CORE_STATUS_U7 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U7  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_M  ((PCNT_CORE_STATUS_U7_V)<<(PCNT_CORE_STATUS_U7_S))
+#define PCNT_CORE_STATUS_U7_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_S  0
+
+#define PCNT_CTRL_REG          (DR_REG_PCNT_BASE + 0x00b0)
+
+/* PCNT_CLK_EN : R/W ;bitpos:[16] ;default: 1'b0 ; */
+
+#define PCNT_CLK_EN  (BIT(16))
+#define PCNT_CLK_EN_M  (BIT(16))
+#define PCNT_CLK_EN_V  0x1
+#define PCNT_CLK_EN_S  16
+
+/* PCNT_CNT_PAUSE_U7 : R/W ;bitpos:[15] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit7's counter. */
+
+#define PCNT_CNT_PAUSE_U7  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_M  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_V  0x1
+#define PCNT_CNT_PAUSE_U7_S  15
+
+/* PCNT_PLUS_CNT_RST_U7 : R/W ;bitpos:[14] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit7's counter. */
+
+#define PCNT_PLUS_CNT_RST_U7  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_M  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_V  0x1
+#define PCNT_PLUS_CNT_RST_U7_S  14
+
+/* PCNT_CNT_PAUSE_U6 : R/W ;bitpos:[13] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit6's counter. */
+
+#define PCNT_CNT_PAUSE_U6  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_M  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_V  0x1
+#define PCNT_CNT_PAUSE_U6_S  13
+
+/* PCNT_PLUS_CNT_RST_U6 : R/W ;bitpos:[12] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit6's counter. */
+
+#define PCNT_PLUS_CNT_RST_U6  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_M  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_V  0x1
+#define PCNT_PLUS_CNT_RST_U6_S  12
+
+/* PCNT_CNT_PAUSE_U5 : R/W ;bitpos:[11] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit5's counter. */
+
+#define PCNT_CNT_PAUSE_U5  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_M  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_V  0x1
+#define PCNT_CNT_PAUSE_U5_S  11
+
+/* PCNT_PLUS_CNT_RST_U5 : R/W ;bitpos:[10] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit5's counter. */
+
+#define PCNT_PLUS_CNT_RST_U5  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_M  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_V  0x1
+#define PCNT_PLUS_CNT_RST_U5_S  10
+
+/* PCNT_CNT_PAUSE_U4 : R/W ;bitpos:[9] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit4's counter. */
+
+#define PCNT_CNT_PAUSE_U4  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_M  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_V  0x1
+#define PCNT_CNT_PAUSE_U4_S  9
+
+/* PCNT_PLUS_CNT_RST_U4 : R/W ;bitpos:[8] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit4's counter. */
+
+#define PCNT_PLUS_CNT_RST_U4  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_M  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_V  0x1
+#define PCNT_PLUS_CNT_RST_U4_S  8
+
+/* PCNT_CNT_PAUSE_U3 : R/W ;bitpos:[7] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit3's counter. */
+
+#define PCNT_CNT_PAUSE_U3  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_M  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_V  0x1
+#define PCNT_CNT_PAUSE_U3_S  7
+
+/* PCNT_PLUS_CNT_RST_U3 : R/W ;bitpos:[6] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit3's counter. */
+
+#define PCNT_PLUS_CNT_RST_U3  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_M  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_V  0x1
+#define PCNT_PLUS_CNT_RST_U3_S  6
+
+/* PCNT_CNT_PAUSE_U2 : R/W ;bitpos:[5] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit2's counter. */
+
+#define PCNT_CNT_PAUSE_U2  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_M  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_V  0x1
+#define PCNT_CNT_PAUSE_U2_S  5
+
+/* PCNT_PLUS_CNT_RST_U2 : R/W ;bitpos:[4] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit2's counter. */
+
+#define PCNT_PLUS_CNT_RST_U2  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_M  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_V  0x1
+#define PCNT_PLUS_CNT_RST_U2_S  4
+
+/* PCNT_CNT_PAUSE_U1 : R/W ;bitpos:[3] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit1's counter. */
+
+#define PCNT_CNT_PAUSE_U1  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_M  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_V  0x1
+#define PCNT_CNT_PAUSE_U1_S  3
+
+/* PCNT_PLUS_CNT_RST_U1 : R/W ;bitpos:[2] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit1's counter. */
+
+#define PCNT_PLUS_CNT_RST_U1  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_M  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_V  0x1
+#define PCNT_PLUS_CNT_RST_U1_S  2
+
+/* PCNT_CNT_PAUSE_U0 : R/W ;bitpos:[1] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit0's counter. */
+
+#define PCNT_CNT_PAUSE_U0  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_M  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_V  0x1
+#define PCNT_CNT_PAUSE_U0_S  1
+
+/* PCNT_PLUS_CNT_RST_U0 : R/W ;bitpos:[0] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit0's counter. */
+
+#define PCNT_PLUS_CNT_RST_U0  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_M  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_V  0x1
+#define PCNT_PLUS_CNT_RST_U0_S  0
+
+#define PCNT_DATE_REG          (DR_REG_PCNT_BASE + 0x00fc)
+
+/* PCNT_DATE : R/W ;bitpos:[31:0] ;default: 32'h14122600 ; */
+
+#define PCNT_DATE    0xFFFFFFFF
+#define PCNT_DATE_M  ((PCNT_DATE_V)<<(PCNT_DATE_S))

Review Comment:
   ```suggestion
   #define PCNT_DATE_M  ((PCNT_DATE_V) << (PCNT_DATE_S))
   ```
   if this is not auto-generated



##########
arch/xtensa/src/esp32/hardware/esp32_pcnt.h:
##########
@@ -0,0 +1,2495 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/hardware/esp32_pcnt.h
+ *
+ * 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_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+#define __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* PCNT_U0_CONF0_REG register
+ * Configuration register 0 for unit 0
+ */
+
+#define PCNT_U0_CONF0_REG (DR_REG_PCNT_BASE + 0x0)
+
+/* PCNT_CH1_LCTRL_MODE_U0 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_M  (PCNT_CH1_LCTRL_MODE_U0_V << PCNT_CH1_LCTRL_MODE_U0_S)
+#define PCNT_CH1_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U0 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_M  (PCNT_CH1_HCTRL_MODE_U0_V << PCNT_CH1_HCTRL_MODE_U0_S)
+#define PCNT_CH1_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_S  28
+
+/* PCNT_CH1_POS_MODE_U0 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U0    0x00000003
+#define PCNT_CH1_POS_MODE_U0_M  (PCNT_CH1_POS_MODE_U0_V << PCNT_CH1_POS_MODE_U0_S)
+#define PCNT_CH1_POS_MODE_U0_V  0x00000003
+#define PCNT_CH1_POS_MODE_U0_S  26
+
+/* PCNT_CH1_NEG_MODE_U0 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U0    0x00000003
+#define PCNT_CH1_NEG_MODE_U0_M  (PCNT_CH1_NEG_MODE_U0_V << PCNT_CH1_NEG_MODE_U0_S)
+#define PCNT_CH1_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U0_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U0 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_M  (PCNT_CH0_LCTRL_MODE_U0_V << PCNT_CH0_LCTRL_MODE_U0_S)
+#define PCNT_CH0_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U0 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_M  (PCNT_CH0_HCTRL_MODE_U0_V << PCNT_CH0_HCTRL_MODE_U0_S)
+#define PCNT_CH0_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_S  20
+
+/* PCNT_CH0_POS_MODE_U0 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U0    0x00000003
+#define PCNT_CH0_POS_MODE_U0_M  (PCNT_CH0_POS_MODE_U0_V << PCNT_CH0_POS_MODE_U0_S)
+#define PCNT_CH0_POS_MODE_U0_V  0x00000003
+#define PCNT_CH0_POS_MODE_U0_S  18
+
+/* PCNT_CH0_NEG_MODE_U0 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U0    0x00000003
+#define PCNT_CH0_NEG_MODE_U0_M  (PCNT_CH0_NEG_MODE_U0_V << PCNT_CH0_NEG_MODE_U0_S)
+#define PCNT_CH0_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U0_S  16
+
+/* PCNT_THR_THRES1_EN_U0 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 0's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U0    (BIT(15))
+#define PCNT_THR_THRES1_EN_U0_M  (PCNT_THR_THRES1_EN_U0_V << PCNT_THR_THRES1_EN_U0_S)
+#define PCNT_THR_THRES1_EN_U0_V  0x00000001
+#define PCNT_THR_THRES1_EN_U0_S  15
+
+/* PCNT_THR_THRES0_EN_U0 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 0's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U0    (BIT(14))
+#define PCNT_THR_THRES0_EN_U0_M  (PCNT_THR_THRES0_EN_U0_V << PCNT_THR_THRES0_EN_U0_S)
+#define PCNT_THR_THRES0_EN_U0_V  0x00000001
+#define PCNT_THR_THRES0_EN_U0_S  14
+
+/* PCNT_THR_L_LIM_EN_U0 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 0's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U0    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U0_M  (PCNT_THR_L_LIM_EN_U0_V << PCNT_THR_L_LIM_EN_U0_S)
+#define PCNT_THR_L_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U0_S  13
+
+/* PCNT_THR_H_LIM_EN_U0 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 0's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U0    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U0_M  (PCNT_THR_H_LIM_EN_U0_V << PCNT_THR_H_LIM_EN_U0_S)
+#define PCNT_THR_H_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U0_S  12
+
+/* PCNT_THR_ZERO_EN_U0 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 0's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U0    (BIT(11))
+#define PCNT_THR_ZERO_EN_U0_M  (PCNT_THR_ZERO_EN_U0_V << PCNT_THR_ZERO_EN_U0_S)
+#define PCNT_THR_ZERO_EN_U0_V  0x00000001
+#define PCNT_THR_ZERO_EN_U0_S  11
+
+/* PCNT_FILTER_EN_U0 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 0's input filter.
+ */
+
+#define PCNT_FILTER_EN_U0    (BIT(10))
+#define PCNT_FILTER_EN_U0_M  (PCNT_FILTER_EN_U0_V << PCNT_FILTER_EN_U0_S)
+#define PCNT_FILTER_EN_U0_V  0x00000001
+#define PCNT_FILTER_EN_U0_S  10
+
+/* PCNT_FILTER_THRES_U0 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U0    0x000003ff
+#define PCNT_FILTER_THRES_U0_M  (PCNT_FILTER_THRES_U0_V << PCNT_FILTER_THRES_U0_S)
+#define PCNT_FILTER_THRES_U0_V  0x000003ff
+#define PCNT_FILTER_THRES_U0_S  0
+
+/* PCNT_U0_CONF1_REG register
+ * Configuration register 1 for unit 0
+ */
+
+#define PCNT_U0_CONF1_REG (DR_REG_PCNT_BASE + 0x4)
+
+/* PCNT_CNT_THRES1_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES1_U0    0x0000ffff
+#define PCNT_CNT_THRES1_U0_M  (PCNT_CNT_THRES1_U0_V << PCNT_CNT_THRES1_U0_S)
+#define PCNT_CNT_THRES1_U0_V  0x0000ffff
+#define PCNT_CNT_THRES1_U0_S  16
+
+/* PCNT_CNT_THRES0_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES0_U0    0x0000ffff
+#define PCNT_CNT_THRES0_U0_M  (PCNT_CNT_THRES0_U0_V << PCNT_CNT_THRES0_U0_S)
+#define PCNT_CNT_THRES0_U0_V  0x0000ffff
+#define PCNT_CNT_THRES0_U0_S  0
+
+/* PCNT_U0_CONF2_REG register
+ * Configuration register 2 for unit 0
+ */
+
+#define PCNT_U0_CONF2_REG (DR_REG_PCNT_BASE + 0x8)
+
+/* PCNT_CNT_L_LIM_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 0.
+ */
+
+#define PCNT_CNT_L_LIM_U0    0x0000ffff
+#define PCNT_CNT_L_LIM_U0_M  (PCNT_CNT_L_LIM_U0_V << PCNT_CNT_L_LIM_U0_S)
+#define PCNT_CNT_L_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U0_S  16
+
+/* PCNT_CNT_H_LIM_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 0.
+ */
+
+#define PCNT_CNT_H_LIM_U0    0x0000ffff
+#define PCNT_CNT_H_LIM_U0_M  (PCNT_CNT_H_LIM_U0_V << PCNT_CNT_H_LIM_U0_S)
+#define PCNT_CNT_H_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U0_S  0
+
+/* PCNT_U1_CONF0_REG register
+ * Configuration register 0 for unit 1
+ */
+
+#define PCNT_U1_CONF0_REG (DR_REG_PCNT_BASE + 0xc)
+
+/* PCNT_CH1_LCTRL_MODE_U1 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_M  (PCNT_CH1_LCTRL_MODE_U1_V << PCNT_CH1_LCTRL_MODE_U1_S)
+#define PCNT_CH1_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U1 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_M  (PCNT_CH1_HCTRL_MODE_U1_V << PCNT_CH1_HCTRL_MODE_U1_S)
+#define PCNT_CH1_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_S  28
+
+/* PCNT_CH1_POS_MODE_U1 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U1    0x00000003
+#define PCNT_CH1_POS_MODE_U1_M  (PCNT_CH1_POS_MODE_U1_V << PCNT_CH1_POS_MODE_U1_S)
+#define PCNT_CH1_POS_MODE_U1_V  0x00000003
+#define PCNT_CH1_POS_MODE_U1_S  26
+
+/* PCNT_CH1_NEG_MODE_U1 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U1    0x00000003
+#define PCNT_CH1_NEG_MODE_U1_M  (PCNT_CH1_NEG_MODE_U1_V << PCNT_CH1_NEG_MODE_U1_S)
+#define PCNT_CH1_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U1_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U1 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_M  (PCNT_CH0_LCTRL_MODE_U1_V << PCNT_CH0_LCTRL_MODE_U1_S)
+#define PCNT_CH0_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U1 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_M  (PCNT_CH0_HCTRL_MODE_U1_V << PCNT_CH0_HCTRL_MODE_U1_S)
+#define PCNT_CH0_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_S  20
+
+/* PCNT_CH0_POS_MODE_U1 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U1    0x00000003
+#define PCNT_CH0_POS_MODE_U1_M  (PCNT_CH0_POS_MODE_U1_V << PCNT_CH0_POS_MODE_U1_S)
+#define PCNT_CH0_POS_MODE_U1_V  0x00000003
+#define PCNT_CH0_POS_MODE_U1_S  18
+
+/* PCNT_CH0_NEG_MODE_U1 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U1    0x00000003
+#define PCNT_CH0_NEG_MODE_U1_M  (PCNT_CH0_NEG_MODE_U1_V << PCNT_CH0_NEG_MODE_U1_S)
+#define PCNT_CH0_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U1_S  16
+
+/* PCNT_THR_THRES1_EN_U1 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 1's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U1    (BIT(15))
+#define PCNT_THR_THRES1_EN_U1_M  (PCNT_THR_THRES1_EN_U1_V << PCNT_THR_THRES1_EN_U1_S)
+#define PCNT_THR_THRES1_EN_U1_V  0x00000001
+#define PCNT_THR_THRES1_EN_U1_S  15
+
+/* PCNT_THR_THRES0_EN_U1 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 1's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U1    (BIT(14))
+#define PCNT_THR_THRES0_EN_U1_M  (PCNT_THR_THRES0_EN_U1_V << PCNT_THR_THRES0_EN_U1_S)
+#define PCNT_THR_THRES0_EN_U1_V  0x00000001
+#define PCNT_THR_THRES0_EN_U1_S  14
+
+/* PCNT_THR_L_LIM_EN_U1 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 1's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U1    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U1_M  (PCNT_THR_L_LIM_EN_U1_V << PCNT_THR_L_LIM_EN_U1_S)
+#define PCNT_THR_L_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U1_S  13
+
+/* PCNT_THR_H_LIM_EN_U1 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 1's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U1    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U1_M  (PCNT_THR_H_LIM_EN_U1_V << PCNT_THR_H_LIM_EN_U1_S)
+#define PCNT_THR_H_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U1_S  12
+
+/* PCNT_THR_ZERO_EN_U1 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 1's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U1    (BIT(11))
+#define PCNT_THR_ZERO_EN_U1_M  (PCNT_THR_ZERO_EN_U1_V << PCNT_THR_ZERO_EN_U1_S)
+#define PCNT_THR_ZERO_EN_U1_V  0x00000001
+#define PCNT_THR_ZERO_EN_U1_S  11
+
+/* PCNT_FILTER_EN_U1 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 1's input filter.
+ */
+
+#define PCNT_FILTER_EN_U1    (BIT(10))
+#define PCNT_FILTER_EN_U1_M  (PCNT_FILTER_EN_U1_V << PCNT_FILTER_EN_U1_S)
+#define PCNT_FILTER_EN_U1_V  0x00000001
+#define PCNT_FILTER_EN_U1_S  10
+
+/* PCNT_FILTER_THRES_U1 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U1    0x000003ff
+#define PCNT_FILTER_THRES_U1_M  (PCNT_FILTER_THRES_U1_V << PCNT_FILTER_THRES_U1_S)
+#define PCNT_FILTER_THRES_U1_V  0x000003ff
+#define PCNT_FILTER_THRES_U1_S  0
+
+/* PCNT_U1_CONF1_REG register
+ * Configuration register 1 for unit 1
+ */
+
+#define PCNT_U1_CONF1_REG (DR_REG_PCNT_BASE + 0x10)
+
+/* PCNT_CNT_THRES1_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES1_U1    0x0000ffff
+#define PCNT_CNT_THRES1_U1_M  (PCNT_CNT_THRES1_U1_V << PCNT_CNT_THRES1_U1_S)
+#define PCNT_CNT_THRES1_U1_V  0x0000ffff
+#define PCNT_CNT_THRES1_U1_S  16
+
+/* PCNT_CNT_THRES0_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES0_U1    0x0000ffff
+#define PCNT_CNT_THRES0_U1_M  (PCNT_CNT_THRES0_U1_V << PCNT_CNT_THRES0_U1_S)
+#define PCNT_CNT_THRES0_U1_V  0x0000ffff
+#define PCNT_CNT_THRES0_U1_S  0
+
+/* PCNT_U1_CONF2_REG register
+ * Configuration register 2 for unit 1
+ */
+
+#define PCNT_U1_CONF2_REG (DR_REG_PCNT_BASE + 0x14)
+
+/* PCNT_CNT_L_LIM_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 1.
+ */
+
+#define PCNT_CNT_L_LIM_U1    0x0000ffff
+#define PCNT_CNT_L_LIM_U1_M  (PCNT_CNT_L_LIM_U1_V << PCNT_CNT_L_LIM_U1_S)
+#define PCNT_CNT_L_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U1_S  16
+
+/* PCNT_CNT_H_LIM_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 1.
+ */
+
+#define PCNT_CNT_H_LIM_U1    0x0000ffff
+#define PCNT_CNT_H_LIM_U1_M  (PCNT_CNT_H_LIM_U1_V << PCNT_CNT_H_LIM_U1_S)
+#define PCNT_CNT_H_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U1_S  0
+
+/* PCNT_U2_CONF0_REG register
+ * Configuration register 0 for unit 2
+ */
+
+#define PCNT_U2_CONF0_REG (DR_REG_PCNT_BASE + 0x18)
+
+/* PCNT_CH1_LCTRL_MODE_U2 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_M  (PCNT_CH1_LCTRL_MODE_U2_V << PCNT_CH1_LCTRL_MODE_U2_S)
+#define PCNT_CH1_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U2 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_M  (PCNT_CH1_HCTRL_MODE_U2_V << PCNT_CH1_HCTRL_MODE_U2_S)
+#define PCNT_CH1_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_S  28
+
+/* PCNT_CH1_POS_MODE_U2 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U2    0x00000003
+#define PCNT_CH1_POS_MODE_U2_M  (PCNT_CH1_POS_MODE_U2_V << PCNT_CH1_POS_MODE_U2_S)
+#define PCNT_CH1_POS_MODE_U2_V  0x00000003
+#define PCNT_CH1_POS_MODE_U2_S  26
+
+/* PCNT_CH1_NEG_MODE_U2 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U2    0x00000003
+#define PCNT_CH1_NEG_MODE_U2_M  (PCNT_CH1_NEG_MODE_U2_V << PCNT_CH1_NEG_MODE_U2_S)
+#define PCNT_CH1_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U2_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U2 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_M  (PCNT_CH0_LCTRL_MODE_U2_V << PCNT_CH0_LCTRL_MODE_U2_S)
+#define PCNT_CH0_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U2 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_M  (PCNT_CH0_HCTRL_MODE_U2_V << PCNT_CH0_HCTRL_MODE_U2_S)
+#define PCNT_CH0_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_S  20
+
+/* PCNT_CH0_POS_MODE_U2 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U2    0x00000003
+#define PCNT_CH0_POS_MODE_U2_M  (PCNT_CH0_POS_MODE_U2_V << PCNT_CH0_POS_MODE_U2_S)
+#define PCNT_CH0_POS_MODE_U2_V  0x00000003
+#define PCNT_CH0_POS_MODE_U2_S  18
+
+/* PCNT_CH0_NEG_MODE_U2 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U2    0x00000003
+#define PCNT_CH0_NEG_MODE_U2_M  (PCNT_CH0_NEG_MODE_U2_V << PCNT_CH0_NEG_MODE_U2_S)
+#define PCNT_CH0_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U2_S  16
+
+/* PCNT_THR_THRES1_EN_U2 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 2's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U2    (BIT(15))
+#define PCNT_THR_THRES1_EN_U2_M  (PCNT_THR_THRES1_EN_U2_V << PCNT_THR_THRES1_EN_U2_S)
+#define PCNT_THR_THRES1_EN_U2_V  0x00000001
+#define PCNT_THR_THRES1_EN_U2_S  15
+
+/* PCNT_THR_THRES0_EN_U2 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 2's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U2    (BIT(14))
+#define PCNT_THR_THRES0_EN_U2_M  (PCNT_THR_THRES0_EN_U2_V << PCNT_THR_THRES0_EN_U2_S)
+#define PCNT_THR_THRES0_EN_U2_V  0x00000001
+#define PCNT_THR_THRES0_EN_U2_S  14
+
+/* PCNT_THR_L_LIM_EN_U2 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 2's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U2    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U2_M  (PCNT_THR_L_LIM_EN_U2_V << PCNT_THR_L_LIM_EN_U2_S)
+#define PCNT_THR_L_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U2_S  13
+
+/* PCNT_THR_H_LIM_EN_U2 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 2's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U2    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U2_M  (PCNT_THR_H_LIM_EN_U2_V << PCNT_THR_H_LIM_EN_U2_S)
+#define PCNT_THR_H_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U2_S  12
+
+/* PCNT_THR_ZERO_EN_U2 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 2's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U2    (BIT(11))
+#define PCNT_THR_ZERO_EN_U2_M  (PCNT_THR_ZERO_EN_U2_V << PCNT_THR_ZERO_EN_U2_S)
+#define PCNT_THR_ZERO_EN_U2_V  0x00000001
+#define PCNT_THR_ZERO_EN_U2_S  11
+
+/* PCNT_FILTER_EN_U2 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 2's input filter.
+ */
+
+#define PCNT_FILTER_EN_U2    (BIT(10))
+#define PCNT_FILTER_EN_U2_M  (PCNT_FILTER_EN_U2_V << PCNT_FILTER_EN_U2_S)
+#define PCNT_FILTER_EN_U2_V  0x00000001
+#define PCNT_FILTER_EN_U2_S  10
+
+/* PCNT_FILTER_THRES_U2 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U2    0x000003ff
+#define PCNT_FILTER_THRES_U2_M  (PCNT_FILTER_THRES_U2_V << PCNT_FILTER_THRES_U2_S)
+#define PCNT_FILTER_THRES_U2_V  0x000003ff
+#define PCNT_FILTER_THRES_U2_S  0
+
+/* PCNT_U2_CONF1_REG register
+ * Configuration register 1 for unit 2
+ */
+
+#define PCNT_U2_CONF1_REG (DR_REG_PCNT_BASE + 0x1c)
+
+/* PCNT_CNT_THRES1_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES1_U2    0x0000ffff
+#define PCNT_CNT_THRES1_U2_M  (PCNT_CNT_THRES1_U2_V << PCNT_CNT_THRES1_U2_S)
+#define PCNT_CNT_THRES1_U2_V  0x0000ffff
+#define PCNT_CNT_THRES1_U2_S  16
+
+/* PCNT_CNT_THRES0_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES0_U2    0x0000ffff
+#define PCNT_CNT_THRES0_U2_M  (PCNT_CNT_THRES0_U2_V << PCNT_CNT_THRES0_U2_S)
+#define PCNT_CNT_THRES0_U2_V  0x0000ffff
+#define PCNT_CNT_THRES0_U2_S  0
+
+/* PCNT_U2_CONF2_REG register
+ * Configuration register 2 for unit 2
+ */
+
+#define PCNT_U2_CONF2_REG (DR_REG_PCNT_BASE + 0x20)
+
+/* PCNT_CNT_L_LIM_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 2.
+ */
+
+#define PCNT_CNT_L_LIM_U2    0x0000ffff
+#define PCNT_CNT_L_LIM_U2_M  (PCNT_CNT_L_LIM_U2_V << PCNT_CNT_L_LIM_U2_S)
+#define PCNT_CNT_L_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U2_S  16
+
+/* PCNT_CNT_H_LIM_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 2.
+ */
+
+#define PCNT_CNT_H_LIM_U2    0x0000ffff
+#define PCNT_CNT_H_LIM_U2_M  (PCNT_CNT_H_LIM_U2_V << PCNT_CNT_H_LIM_U2_S)
+#define PCNT_CNT_H_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U2_S  0
+
+/* PCNT_U3_CONF0_REG register
+ * Configuration register 0 for unit 3
+ */
+
+#define PCNT_U3_CONF0_REG (DR_REG_PCNT_BASE + 0x24)
+
+/* PCNT_CH1_LCTRL_MODE_U3 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_M  (PCNT_CH1_LCTRL_MODE_U3_V << PCNT_CH1_LCTRL_MODE_U3_S)
+#define PCNT_CH1_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U3 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_M  (PCNT_CH1_HCTRL_MODE_U3_V << PCNT_CH1_HCTRL_MODE_U3_S)
+#define PCNT_CH1_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_S  28
+
+/* PCNT_CH1_POS_MODE_U3 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U3    0x00000003
+#define PCNT_CH1_POS_MODE_U3_M  (PCNT_CH1_POS_MODE_U3_V << PCNT_CH1_POS_MODE_U3_S)
+#define PCNT_CH1_POS_MODE_U3_V  0x00000003
+#define PCNT_CH1_POS_MODE_U3_S  26
+
+/* PCNT_CH1_NEG_MODE_U3 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U3    0x00000003
+#define PCNT_CH1_NEG_MODE_U3_M  (PCNT_CH1_NEG_MODE_U3_V << PCNT_CH1_NEG_MODE_U3_S)
+#define PCNT_CH1_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U3_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U3 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_M  (PCNT_CH0_LCTRL_MODE_U3_V << PCNT_CH0_LCTRL_MODE_U3_S)
+#define PCNT_CH0_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U3 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_M  (PCNT_CH0_HCTRL_MODE_U3_V << PCNT_CH0_HCTRL_MODE_U3_S)
+#define PCNT_CH0_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_S  20
+
+/* PCNT_CH0_POS_MODE_U3 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U3    0x00000003
+#define PCNT_CH0_POS_MODE_U3_M  (PCNT_CH0_POS_MODE_U3_V << PCNT_CH0_POS_MODE_U3_S)
+#define PCNT_CH0_POS_MODE_U3_V  0x00000003
+#define PCNT_CH0_POS_MODE_U3_S  18
+
+/* PCNT_CH0_NEG_MODE_U3 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U3    0x00000003
+#define PCNT_CH0_NEG_MODE_U3_M  (PCNT_CH0_NEG_MODE_U3_V << PCNT_CH0_NEG_MODE_U3_S)
+#define PCNT_CH0_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U3_S  16
+
+/* PCNT_THR_THRES1_EN_U3 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 3's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U3    (BIT(15))
+#define PCNT_THR_THRES1_EN_U3_M  (PCNT_THR_THRES1_EN_U3_V << PCNT_THR_THRES1_EN_U3_S)
+#define PCNT_THR_THRES1_EN_U3_V  0x00000001
+#define PCNT_THR_THRES1_EN_U3_S  15
+
+/* PCNT_THR_THRES0_EN_U3 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 3's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U3    (BIT(14))
+#define PCNT_THR_THRES0_EN_U3_M  (PCNT_THR_THRES0_EN_U3_V << PCNT_THR_THRES0_EN_U3_S)
+#define PCNT_THR_THRES0_EN_U3_V  0x00000001
+#define PCNT_THR_THRES0_EN_U3_S  14
+
+/* PCNT_THR_L_LIM_EN_U3 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 3's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U3    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U3_M  (PCNT_THR_L_LIM_EN_U3_V << PCNT_THR_L_LIM_EN_U3_S)
+#define PCNT_THR_L_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U3_S  13
+
+/* PCNT_THR_H_LIM_EN_U3 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 3's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U3    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U3_M  (PCNT_THR_H_LIM_EN_U3_V << PCNT_THR_H_LIM_EN_U3_S)
+#define PCNT_THR_H_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U3_S  12
+
+/* PCNT_THR_ZERO_EN_U3 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 3's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U3    (BIT(11))
+#define PCNT_THR_ZERO_EN_U3_M  (PCNT_THR_ZERO_EN_U3_V << PCNT_THR_ZERO_EN_U3_S)
+#define PCNT_THR_ZERO_EN_U3_V  0x00000001
+#define PCNT_THR_ZERO_EN_U3_S  11
+
+/* PCNT_FILTER_EN_U3 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 3's input filter.
+ */
+
+#define PCNT_FILTER_EN_U3    (BIT(10))
+#define PCNT_FILTER_EN_U3_M  (PCNT_FILTER_EN_U3_V << PCNT_FILTER_EN_U3_S)
+#define PCNT_FILTER_EN_U3_V  0x00000001
+#define PCNT_FILTER_EN_U3_S  10
+
+/* PCNT_FILTER_THRES_U3 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U3    0x000003ff
+#define PCNT_FILTER_THRES_U3_M  (PCNT_FILTER_THRES_U3_V << PCNT_FILTER_THRES_U3_S)
+#define PCNT_FILTER_THRES_U3_V  0x000003ff
+#define PCNT_FILTER_THRES_U3_S  0
+
+/* PCNT_U3_CONF1_REG register
+ * Configuration register 1 for unit 3
+ */
+
+#define PCNT_U3_CONF1_REG (DR_REG_PCNT_BASE + 0x28)
+
+/* PCNT_CNT_THRES1_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES1_U3    0x0000ffff
+#define PCNT_CNT_THRES1_U3_M  (PCNT_CNT_THRES1_U3_V << PCNT_CNT_THRES1_U3_S)
+#define PCNT_CNT_THRES1_U3_V  0x0000ffff
+#define PCNT_CNT_THRES1_U3_S  16
+
+/* PCNT_CNT_THRES0_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES0_U3    0x0000ffff
+#define PCNT_CNT_THRES0_U3_M  (PCNT_CNT_THRES0_U3_V << PCNT_CNT_THRES0_U3_S)
+#define PCNT_CNT_THRES0_U3_V  0x0000ffff
+#define PCNT_CNT_THRES0_U3_S  0
+
+/* PCNT_U3_CONF2_REG register
+ * Configuration register 2 for unit 3
+ */
+
+#define PCNT_U3_CONF2_REG (DR_REG_PCNT_BASE + 0x2c)
+
+/* PCNT_CNT_L_LIM_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 3.
+ */
+
+#define PCNT_CNT_L_LIM_U3    0x0000ffff
+#define PCNT_CNT_L_LIM_U3_M  (PCNT_CNT_L_LIM_U3_V << PCNT_CNT_L_LIM_U3_S)
+#define PCNT_CNT_L_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U3_S  16
+
+/* PCNT_CNT_H_LIM_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 3.
+ */
+
+#define PCNT_CNT_H_LIM_U3    0x0000ffff
+#define PCNT_CNT_H_LIM_U3_M  (PCNT_CNT_H_LIM_U3_V << PCNT_CNT_H_LIM_U3_S)
+#define PCNT_CNT_H_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U3_S  0
+
+#define PCNT_U4_CONF0_REG          (DR_REG_PCNT_BASE + 0x0030)
+
+/* PCNT_CH1_LCTRL_MODE_U4 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U4_M  ((PCNT_CH1_LCTRL_MODE_U4_V)<<(PCNT_CH1_LCTRL_MODE_U4_S))
+#define PCNT_CH1_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U4_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U4 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U4_M  ((PCNT_CH1_HCTRL_MODE_U4_V)<<(PCNT_CH1_HCTRL_MODE_U4_S))
+#define PCNT_CH1_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U4_S  28
+
+/* PCNT_CH1_POS_MODE_U4 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U4  0x00000003
+#define PCNT_CH1_POS_MODE_U4_M  ((PCNT_CH1_POS_MODE_U4_V)<<(PCNT_CH1_POS_MODE_U4_S))
+#define PCNT_CH1_POS_MODE_U4_V  0x3
+#define PCNT_CH1_POS_MODE_U4_S  26
+
+/* PCNT_CH1_NEG_MODE_U4 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U4  0x00000003
+#define PCNT_CH1_NEG_MODE_U4_M  ((PCNT_CH1_NEG_MODE_U4_V)<<(PCNT_CH1_NEG_MODE_U4_S))
+#define PCNT_CH1_NEG_MODE_U4_V  0x3
+#define PCNT_CH1_NEG_MODE_U4_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U4 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U4_M  ((PCNT_CH0_LCTRL_MODE_U4_V)<<(PCNT_CH0_LCTRL_MODE_U4_S))
+#define PCNT_CH0_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U4_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U4 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U4_M  ((PCNT_CH0_HCTRL_MODE_U4_V)<<(PCNT_CH0_HCTRL_MODE_U4_S))
+#define PCNT_CH0_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U4_S  20
+
+/* PCNT_CH0_POS_MODE_U4 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U4  0x00000003
+#define PCNT_CH0_POS_MODE_U4_M  ((PCNT_CH0_POS_MODE_U4_V)<<(PCNT_CH0_POS_MODE_U4_S))
+#define PCNT_CH0_POS_MODE_U4_V  0x3
+#define PCNT_CH0_POS_MODE_U4_S  18
+
+/* PCNT_CH0_NEG_MODE_U4 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U4  0x00000003
+#define PCNT_CH0_NEG_MODE_U4_M  ((PCNT_CH0_NEG_MODE_U4_V)<<(PCNT_CH0_NEG_MODE_U4_S))
+#define PCNT_CH0_NEG_MODE_U4_V  0x3
+#define PCNT_CH0_NEG_MODE_U4_S  16
+
+/* PCNT_THR_THRES1_EN_U4 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U4  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_V  0x1
+#define PCNT_THR_THRES1_EN_U4_S  15
+
+/* PCNT_THR_THRES0_EN_U4 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U4  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_V  0x1
+#define PCNT_THR_THRES0_EN_U4_S  14
+
+/* PCNT_THR_L_LIM_EN_U4 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_l_lim  value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U4  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_V  0x1
+#define PCNT_THR_L_LIM_EN_U4_S  13
+
+/* PCNT_THR_H_LIM_EN_U4 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U4  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_V  0x1
+#define PCNT_THR_H_LIM_EN_U4_S  12
+
+/* PCNT_THR_ZERO_EN_U4 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U4  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_V  0x1
+#define PCNT_THR_ZERO_EN_U4_S  11
+
+/* PCNT_FILTER_EN_U4 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit4.
+ */
+
+#define PCNT_FILTER_EN_U4  (BIT(10))
+#define PCNT_FILTER_EN_U4_M  (BIT(10))
+#define PCNT_FILTER_EN_U4_V  0x1
+#define PCNT_FILTER_EN_U4_S  10
+
+/* PCNT_FILTER_THRES_U4 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit4.
+ */
+
+#define PCNT_FILTER_THRES_U4  0x000003FF
+#define PCNT_FILTER_THRES_U4_M  ((PCNT_FILTER_THRES_U4_V)<<(PCNT_FILTER_THRES_U4_S))
+#define PCNT_FILTER_THRES_U4_V  0x3FF
+#define PCNT_FILTER_THRES_U4_S  0
+
+#define PCNT_U4_CONF1_REG          (DR_REG_PCNT_BASE + 0x0034)
+
+/* PCNT_CNT_THRES1_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure thres1 value for unit4.
+ */
+
+#define PCNT_CNT_THRES1_U4  0x0000FFFF
+#define PCNT_CNT_THRES1_U4_M  ((PCNT_CNT_THRES1_U4_V)<<(PCNT_CNT_THRES1_U4_S))
+#define PCNT_CNT_THRES1_U4_V  0xFFFF
+#define PCNT_CNT_THRES1_U4_S  16
+
+/* PCNT_CNT_THRES0_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit4.
+ */
+
+#define PCNT_CNT_THRES0_U4  0x0000FFFF
+#define PCNT_CNT_THRES0_U4_M  ((PCNT_CNT_THRES0_U4_V)<<(PCNT_CNT_THRES0_U4_S))
+#define PCNT_CNT_THRES0_U4_V  0xFFFF
+#define PCNT_CNT_THRES0_U4_S  0
+
+#define PCNT_U4_CONF2_REG          (DR_REG_PCNT_BASE + 0x0038)
+
+/* PCNT_CNT_L_LIM_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit4.
+ */
+
+#define PCNT_CNT_L_LIM_U4  0x0000FFFF
+#define PCNT_CNT_L_LIM_U4_M  ((PCNT_CNT_L_LIM_U4_V)<<(PCNT_CNT_L_LIM_U4_S))
+#define PCNT_CNT_L_LIM_U4_V  0xFFFF
+#define PCNT_CNT_L_LIM_U4_S  16
+
+/* PCNT_CNT_H_LIM_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit4.
+ */
+
+#define PCNT_CNT_H_LIM_U4  0x0000FFFF
+#define PCNT_CNT_H_LIM_U4_M  ((PCNT_CNT_H_LIM_U4_V)<<(PCNT_CNT_H_LIM_U4_S))
+#define PCNT_CNT_H_LIM_U4_V  0xFFFF
+#define PCNT_CNT_H_LIM_U4_S  0
+
+#define PCNT_U5_CONF0_REG          (DR_REG_PCNT_BASE + 0x003c)
+
+/* PCNT_CH1_LCTRL_MODE_U5 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U5_M  ((PCNT_CH1_LCTRL_MODE_U5_V)<<(PCNT_CH1_LCTRL_MODE_U5_S))
+#define PCNT_CH1_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U5_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U5 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U5_M  ((PCNT_CH1_HCTRL_MODE_U5_V)<<(PCNT_CH1_HCTRL_MODE_U5_S))
+#define PCNT_CH1_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U5_S  28
+
+/* PCNT_CH1_POS_MODE_U5 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U5  0x00000003
+#define PCNT_CH1_POS_MODE_U5_M  ((PCNT_CH1_POS_MODE_U5_V)<<(PCNT_CH1_POS_MODE_U5_S))
+#define PCNT_CH1_POS_MODE_U5_V  0x3
+#define PCNT_CH1_POS_MODE_U5_S  26
+
+/* PCNT_CH1_NEG_MODE_U5 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U5  0x00000003
+#define PCNT_CH1_NEG_MODE_U5_M  ((PCNT_CH1_NEG_MODE_U5_V)<<(PCNT_CH1_NEG_MODE_U5_S))
+#define PCNT_CH1_NEG_MODE_U5_V  0x3
+#define PCNT_CH1_NEG_MODE_U5_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U5 : R/W ;bitpos:[23:22] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U5_M  ((PCNT_CH0_LCTRL_MODE_U5_V)<<(PCNT_CH0_LCTRL_MODE_U5_S))
+#define PCNT_CH0_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U5_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U5 : R/W ;bitpos:[21:20] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's high
+ * control signal for unit5.
+ * 0:increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U5_M  ((PCNT_CH0_HCTRL_MODE_U5_V)<<(PCNT_CH0_HCTRL_MODE_U5_S))
+#define PCNT_CH0_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U5_S  20
+
+/* PCNT_CH0_POS_MODE_U5 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U5  0x00000003
+#define PCNT_CH0_POS_MODE_U5_M  ((PCNT_CH0_POS_MODE_U5_V)<<(PCNT_CH0_POS_MODE_U5_S))
+#define PCNT_CH0_POS_MODE_U5_V  0x3
+#define PCNT_CH0_POS_MODE_U5_S  18
+
+/* PCNT_CH0_NEG_MODE_U5 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U5  0x00000003
+#define PCNT_CH0_NEG_MODE_U5_M  ((PCNT_CH0_NEG_MODE_U5_V)<<(PCNT_CH0_NEG_MODE_U5_S))
+#define PCNT_CH0_NEG_MODE_U5_V  0x3
+#define PCNT_CH0_NEG_MODE_U5_S  16
+
+/* PCNT_THR_THRES1_EN_U5 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U5  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_V  0x1
+#define PCNT_THR_THRES1_EN_U5_S  15
+
+/* PCNT_THR_THRES0_EN_U5 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U5  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_V  0x1
+#define PCNT_THR_THRES0_EN_U5_S  14
+
+/* PCNT_THR_L_LIM_EN_U5 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U5  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_V  0x1
+#define PCNT_THR_L_LIM_EN_U5_S  13
+
+/* PCNT_THR_H_LIM_EN_U5 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U5  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_V  0x1
+#define PCNT_THR_H_LIM_EN_U5_S  12
+
+/* PCNT_THR_ZERO_EN_U5 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U5  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_V  0x1
+#define PCNT_THR_ZERO_EN_U5_S  11
+
+/* PCNT_FILTER_EN_U5 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit5.
+ */
+
+#define PCNT_FILTER_EN_U5  (BIT(10))
+#define PCNT_FILTER_EN_U5_M  (BIT(10))
+#define PCNT_FILTER_EN_U5_V  0x1
+#define PCNT_FILTER_EN_U5_S  10
+
+/* PCNT_FILTER_THRES_U5 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit5.
+ */
+
+#define PCNT_FILTER_THRES_U5  0x000003FF
+#define PCNT_FILTER_THRES_U5_M  ((PCNT_FILTER_THRES_U5_V)<<(PCNT_FILTER_THRES_U5_S))
+#define PCNT_FILTER_THRES_U5_V  0x3FF
+#define PCNT_FILTER_THRES_U5_S  0
+
+#define PCNT_U5_CONF1_REG          (DR_REG_PCNT_BASE + 0x0040)
+
+/* PCNT_CNT_THRES1_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit5.
+ */
+
+#define PCNT_CNT_THRES1_U5  0x0000FFFF
+#define PCNT_CNT_THRES1_U5_M  ((PCNT_CNT_THRES1_U5_V)<<(PCNT_CNT_THRES1_U5_S))
+#define PCNT_CNT_THRES1_U5_V  0xFFFF
+#define PCNT_CNT_THRES1_U5_S  16
+
+/* PCNT_CNT_THRES0_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit5.
+ */
+
+#define PCNT_CNT_THRES0_U5  0x0000FFFF
+#define PCNT_CNT_THRES0_U5_M  ((PCNT_CNT_THRES0_U5_V)<<(PCNT_CNT_THRES0_U5_S))
+#define PCNT_CNT_THRES0_U5_V  0xFFFF
+#define PCNT_CNT_THRES0_U5_S  0
+
+#define PCNT_U5_CONF2_REG          (DR_REG_PCNT_BASE + 0x0044)
+
+/* PCNT_CNT_L_LIM_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit5.
+ */
+
+#define PCNT_CNT_L_LIM_U5  0x0000FFFF
+#define PCNT_CNT_L_LIM_U5_M  ((PCNT_CNT_L_LIM_U5_V)<<(PCNT_CNT_L_LIM_U5_S))
+#define PCNT_CNT_L_LIM_U5_V  0xFFFF
+#define PCNT_CNT_L_LIM_U5_S  16
+
+/* PCNT_CNT_H_LIM_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit5.
+ */
+
+#define PCNT_CNT_H_LIM_U5  0x0000FFFF
+#define PCNT_CNT_H_LIM_U5_M  ((PCNT_CNT_H_LIM_U5_V)<<(PCNT_CNT_H_LIM_U5_S))
+#define PCNT_CNT_H_LIM_U5_V  0xFFFF
+#define PCNT_CNT_H_LIM_U5_S  0
+
+#define PCNT_U6_CONF0_REG          (DR_REG_PCNT_BASE + 0x0048)
+
+/* PCNT_CH1_LCTRL_MODE_U6 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * low control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U6_M  ((PCNT_CH1_LCTRL_MODE_U6_V)<<(PCNT_CH1_LCTRL_MODE_U6_S))
+#define PCNT_CH1_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U6_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U6 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U6_M  ((PCNT_CH1_HCTRL_MODE_U6_V)<<(PCNT_CH1_HCTRL_MODE_U6_S))
+#define PCNT_CH1_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U6_S  28
+
+/* PCNT_CH1_POS_MODE_U6 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U6  0x00000003
+#define PCNT_CH1_POS_MODE_U6_M  ((PCNT_CH1_POS_MODE_U6_V)<<(PCNT_CH1_POS_MODE_U6_S))
+#define PCNT_CH1_POS_MODE_U6_V  0x3
+#define PCNT_CH1_POS_MODE_U6_S  26
+
+/* PCNT_CH1_NEG_MODE_U6 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * input negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U6  0x00000003
+#define PCNT_CH1_NEG_MODE_U6_M  ((PCNT_CH1_NEG_MODE_U6_V)<<(PCNT_CH1_NEG_MODE_U6_S))
+#define PCNT_CH1_NEG_MODE_U6_V  0x3
+#define PCNT_CH1_NEG_MODE_U6_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U6 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U6_M  ((PCNT_CH0_LCTRL_MODE_U6_V)<<(PCNT_CH0_LCTRL_MODE_U6_S))
+#define PCNT_CH0_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U6_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U6 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * high control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U6_M  ((PCNT_CH0_HCTRL_MODE_U6_V)<<(PCNT_CH0_HCTRL_MODE_U6_S))
+#define PCNT_CH0_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U6_S  20
+
+/* PCNT_CH0_POS_MODE_U6 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U6  0x00000003
+#define PCNT_CH0_POS_MODE_U6_M  ((PCNT_CH0_POS_MODE_U6_V)<<(PCNT_CH0_POS_MODE_U6_S))
+#define PCNT_CH0_POS_MODE_U6_V  0x3
+#define PCNT_CH0_POS_MODE_U6_S  18
+
+/* PCNT_CH0_NEG_MODE_U6 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U6  0x00000003
+#define PCNT_CH0_NEG_MODE_U6_M  ((PCNT_CH0_NEG_MODE_U6_V)<<(PCNT_CH0_NEG_MODE_U6_S))
+#define PCNT_CH0_NEG_MODE_U6_V  0x3
+#define PCNT_CH0_NEG_MODE_U6_S  16
+
+/* PCNT_THR_THRES1_EN_U6 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit6's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U6  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_V  0x1
+#define PCNT_THR_THRES1_EN_U6_S  15
+
+/* PCNT_THR_THRES0_EN_U6 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U6  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_V  0x1
+#define PCNT_THR_THRES0_EN_U6_S  14
+
+/* PCNT_THR_L_LIM_EN_U6 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U6  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_V  0x1
+#define PCNT_THR_L_LIM_EN_U6_S  13
+
+/* PCNT_THR_H_LIM_EN_U6 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit6's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U6  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_V  0x1
+#define PCNT_THR_H_LIM_EN_U6_S  12
+
+/* PCNT_THR_ZERO_EN_U6 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U6  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_V  0x1
+#define PCNT_THR_ZERO_EN_U6_S  11
+
+/* PCNT_FILTER_EN_U6 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit6.
+ */
+
+#define PCNT_FILTER_EN_U6  (BIT(10))
+#define PCNT_FILTER_EN_U6_M  (BIT(10))
+#define PCNT_FILTER_EN_U6_V  0x1
+#define PCNT_FILTER_EN_U6_S  10
+
+/* PCNT_FILTER_THRES_U6 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is
+ * smaller than this value for unit6.
+ */
+
+#define PCNT_FILTER_THRES_U6  0x000003FF
+#define PCNT_FILTER_THRES_U6_M  ((PCNT_FILTER_THRES_U6_V)<<(PCNT_FILTER_THRES_U6_S))
+#define PCNT_FILTER_THRES_U6_V  0x3FF
+#define PCNT_FILTER_THRES_U6_S  0
+
+#define PCNT_U6_CONF1_REG          (DR_REG_PCNT_BASE + 0x004c)
+
+/* PCNT_CNT_THRES1_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit6.
+ */
+
+#define PCNT_CNT_THRES1_U6  0x0000FFFF
+#define PCNT_CNT_THRES1_U6_M  ((PCNT_CNT_THRES1_U6_V)<<(PCNT_CNT_THRES1_U6_S))
+#define PCNT_CNT_THRES1_U6_V  0xFFFF
+#define PCNT_CNT_THRES1_U6_S  16
+
+/* PCNT_CNT_THRES0_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit6.
+ */
+
+#define PCNT_CNT_THRES0_U6  0x0000FFFF
+#define PCNT_CNT_THRES0_U6_M  ((PCNT_CNT_THRES0_U6_V)<<(PCNT_CNT_THRES0_U6_S))
+#define PCNT_CNT_THRES0_U6_V  0xFFFF
+#define PCNT_CNT_THRES0_U6_S  0
+
+#define PCNT_U6_CONF2_REG          (DR_REG_PCNT_BASE + 0x0050)
+
+/* PCNT_CNT_L_LIM_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit6.
+ */
+
+#define PCNT_CNT_L_LIM_U6  0x0000FFFF
+#define PCNT_CNT_L_LIM_U6_M  ((PCNT_CNT_L_LIM_U6_V)<<(PCNT_CNT_L_LIM_U6_S))
+#define PCNT_CNT_L_LIM_U6_V  0xFFFF
+#define PCNT_CNT_L_LIM_U6_S  16
+
+/* PCNT_CNT_H_LIM_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit6.
+ */
+
+#define PCNT_CNT_H_LIM_U6  0x0000FFFF
+#define PCNT_CNT_H_LIM_U6_M  ((PCNT_CNT_H_LIM_U6_V)<<(PCNT_CNT_H_LIM_U6_S))
+#define PCNT_CNT_H_LIM_U6_V  0xFFFF
+#define PCNT_CNT_H_LIM_U6_S  0
+
+#define PCNT_U7_CONF0_REG          (DR_REG_PCNT_BASE + 0x0054)
+
+/* PCNT_CH1_LCTRL_MODE_U7 : R/W ;bitpos:[31:30] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U7_M  ((PCNT_CH1_LCTRL_MODE_U7_V)<<(PCNT_CH1_LCTRL_MODE_U7_S))
+#define PCNT_CH1_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U7_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U7 : R/W ;bitpos:[29:28] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U7_M  ((PCNT_CH1_HCTRL_MODE_U7_V)<<(PCNT_CH1_HCTRL_MODE_U7_S))
+#define PCNT_CH1_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U7_S  28
+
+/* PCNT_CH1_POS_MODE_U7 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2:decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U7  0x00000003
+#define PCNT_CH1_POS_MODE_U7_M  ((PCNT_CH1_POS_MODE_U7_V)<<(PCNT_CH1_POS_MODE_U7_S))
+#define PCNT_CH1_POS_MODE_U7_V  0x3
+#define PCNT_CH1_POS_MODE_U7_S  26
+
+/* PCNT_CH1_NEG_MODE_U7 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U7  0x00000003
+#define PCNT_CH1_NEG_MODE_U7_M  ((PCNT_CH1_NEG_MODE_U7_V)<<(PCNT_CH1_NEG_MODE_U7_S))
+#define PCNT_CH1_NEG_MODE_U7_V  0x3
+#define PCNT_CH1_NEG_MODE_U7_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U7 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U7_M  ((PCNT_CH0_LCTRL_MODE_U7_V)<<(PCNT_CH0_LCTRL_MODE_U7_S))
+#define PCNT_CH0_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U7_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U7 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U7_M  ((PCNT_CH0_HCTRL_MODE_U7_V)<<(PCNT_CH0_HCTRL_MODE_U7_S))
+#define PCNT_CH0_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U7_S  20
+
+/* PCNT_CH0_POS_MODE_U7 : R/W ;bitpos:[19:18] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U7  0x00000003
+#define PCNT_CH0_POS_MODE_U7_M  ((PCNT_CH0_POS_MODE_U7_V)<<(PCNT_CH0_POS_MODE_U7_S))
+#define PCNT_CH0_POS_MODE_U7_V  0x3
+#define PCNT_CH0_POS_MODE_U7_S  18
+
+/* PCNT_CH0_NEG_MODE_U7 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * input negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U7  0x00000003
+#define PCNT_CH0_NEG_MODE_U7_M  ((PCNT_CH0_NEG_MODE_U7_V)<<(PCNT_CH0_NEG_MODE_U7_S))
+#define PCNT_CH0_NEG_MODE_U7_V  0x3
+#define PCNT_CH0_NEG_MODE_U7_S  16
+
+/* PCNT_THR_THRES1_EN_U7 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit7's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U7  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_V  0x1
+#define PCNT_THR_THRES1_EN_U7_S  15
+
+/* PCNT_THR_THRES0_EN_U7 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U7  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_V  0x1
+#define PCNT_THR_THRES0_EN_U7_S  14
+
+/* PCNT_THR_L_LIM_EN_U7 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U7  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_V  0x1
+#define PCNT_THR_L_LIM_EN_U7_S  13
+
+/* PCNT_THR_H_LIM_EN_U7 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit7's count
+ * with thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U7  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_V  0x1
+#define PCNT_THR_H_LIM_EN_U7_S  12
+
+/* PCNT_THR_ZERO_EN_U7 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U7  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_V  0x1
+#define PCNT_THR_ZERO_EN_U7_S  11
+
+/* PCNT_FILTER_EN_U7 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit7.
+ */
+
+#define PCNT_FILTER_EN_U7  (BIT(10))
+#define PCNT_FILTER_EN_U7_M  (BIT(10))
+#define PCNT_FILTER_EN_U7_V  0x1
+#define PCNT_FILTER_EN_U7_S  10
+
+/* PCNT_FILTER_THRES_U7 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit7.
+ */
+
+#define PCNT_FILTER_THRES_U7  0x000003FF
+#define PCNT_FILTER_THRES_U7_M  ((PCNT_FILTER_THRES_U7_V)<<(PCNT_FILTER_THRES_U7_S))
+#define PCNT_FILTER_THRES_U7_V  0x3FF
+#define PCNT_FILTER_THRES_U7_S  0
+
+#define PCNT_U7_CONF1_REG          (DR_REG_PCNT_BASE + 0x0058)
+
+/* PCNT_CNT_THRES1_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit7.
+ */
+
+#define PCNT_CNT_THRES1_U7  0x0000FFFF
+#define PCNT_CNT_THRES1_U7_M  ((PCNT_CNT_THRES1_U7_V)<<(PCNT_CNT_THRES1_U7_S))
+#define PCNT_CNT_THRES1_U7_V  0xFFFF
+#define PCNT_CNT_THRES1_U7_S  16
+
+/* PCNT_CNT_THRES0_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit7.
+ */
+
+#define PCNT_CNT_THRES0_U7  0x0000FFFF
+#define PCNT_CNT_THRES0_U7_M  ((PCNT_CNT_THRES0_U7_V)<<(PCNT_CNT_THRES0_U7_S))
+#define PCNT_CNT_THRES0_U7_V  0xFFFF
+#define PCNT_CNT_THRES0_U7_S  0
+
+#define PCNT_U7_CONF2_REG          (DR_REG_PCNT_BASE + 0x005c)
+
+/* PCNT_CNT_L_LIM_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit7.
+ */
+
+#define PCNT_CNT_L_LIM_U7  0x0000FFFF
+#define PCNT_CNT_L_LIM_U7_M  ((PCNT_CNT_L_LIM_U7_V)<<(PCNT_CNT_L_LIM_U7_S))
+#define PCNT_CNT_L_LIM_U7_V  0xFFFF
+#define PCNT_CNT_L_LIM_U7_S  16
+
+/* PCNT_CNT_H_LIM_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit7.
+ */
+
+#define PCNT_CNT_H_LIM_U7  0x0000FFFF
+#define PCNT_CNT_H_LIM_U7_M  ((PCNT_CNT_H_LIM_U7_V)<<(PCNT_CNT_H_LIM_U7_S))
+#define PCNT_CNT_H_LIM_U7_V  0xFFFF
+#define PCNT_CNT_H_LIM_U7_S  0
+
+#define PCNT_U0_CNT_REG          (DR_REG_PCNT_BASE + 0x0060)
+
+/* PCNT_PLUS_CNT_U0 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit0.
+ */
+
+#define PCNT_PLUS_CNT_U0  0x0000FFFF
+#define PCNT_PLUS_CNT_U0_M  ((PCNT_PLUS_CNT_U0_V)<<(PCNT_PLUS_CNT_U0_S))
+#define PCNT_PLUS_CNT_U0_V  0xFFFF
+#define PCNT_PLUS_CNT_U0_S  0
+
+#define PCNT_U1_CNT_REG          (DR_REG_PCNT_BASE + 0x0064)
+
+/* PCNT_PLUS_CNT_U1 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit1.
+ */
+
+#define PCNT_PLUS_CNT_U1  0x0000FFFF
+#define PCNT_PLUS_CNT_U1_M  ((PCNT_PLUS_CNT_U1_V)<<(PCNT_PLUS_CNT_U1_S))
+#define PCNT_PLUS_CNT_U1_V  0xFFFF
+#define PCNT_PLUS_CNT_U1_S  0
+
+#define PCNT_U2_CNT_REG          (DR_REG_PCNT_BASE + 0x0068)
+
+/* PCNT_PLUS_CNT_U2 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit2.
+ */
+
+#define PCNT_PLUS_CNT_U2  0x0000FFFF
+#define PCNT_PLUS_CNT_U2_M  ((PCNT_PLUS_CNT_U2_V)<<(PCNT_PLUS_CNT_U2_S))
+#define PCNT_PLUS_CNT_U2_V  0xFFFF
+#define PCNT_PLUS_CNT_U2_S  0
+
+#define PCNT_U3_CNT_REG          (DR_REG_PCNT_BASE + 0x006c)
+
+/* PCNT_PLUS_CNT_U3 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit3.
+ */
+
+#define PCNT_PLUS_CNT_U3  0x0000FFFF
+#define PCNT_PLUS_CNT_U3_M  ((PCNT_PLUS_CNT_U3_V)<<(PCNT_PLUS_CNT_U3_S))
+#define PCNT_PLUS_CNT_U3_V  0xFFFF
+#define PCNT_PLUS_CNT_U3_S  0
+
+#define PCNT_U4_CNT_REG          (DR_REG_PCNT_BASE + 0x0070)
+
+/* PCNT_PLUS_CNT_U4 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit4.
+ */
+
+#define PCNT_PLUS_CNT_U4  0x0000FFFF
+#define PCNT_PLUS_CNT_U4_M  ((PCNT_PLUS_CNT_U4_V)<<(PCNT_PLUS_CNT_U4_S))
+#define PCNT_PLUS_CNT_U4_V  0xFFFF
+#define PCNT_PLUS_CNT_U4_S  0
+
+#define PCNT_U5_CNT_REG          (DR_REG_PCNT_BASE + 0x0074)
+
+/* PCNT_PLUS_CNT_U5 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit5.
+ */
+
+#define PCNT_PLUS_CNT_U5  0x0000FFFF
+#define PCNT_PLUS_CNT_U5_M  ((PCNT_PLUS_CNT_U5_V)<<(PCNT_PLUS_CNT_U5_S))
+#define PCNT_PLUS_CNT_U5_V  0xFFFF
+#define PCNT_PLUS_CNT_U5_S  0
+
+#define PCNT_U6_CNT_REG          (DR_REG_PCNT_BASE + 0x0078)
+
+/* PCNT_PLUS_CNT_U6 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit6.
+ */
+
+#define PCNT_PLUS_CNT_U6  0x0000FFFF
+#define PCNT_PLUS_CNT_U6_M  ((PCNT_PLUS_CNT_U6_V)<<(PCNT_PLUS_CNT_U6_S))
+#define PCNT_PLUS_CNT_U6_V  0xFFFF
+#define PCNT_PLUS_CNT_U6_S  0
+
+#define PCNT_U7_CNT_REG          (DR_REG_PCNT_BASE + 0x007c)
+
+/* PCNT_PLUS_CNT_U7 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit7.
+ */
+
+#define PCNT_PLUS_CNT_U7  0x0000FFFF
+#define PCNT_PLUS_CNT_U7_M  ((PCNT_PLUS_CNT_U7_V)<<(PCNT_PLUS_CNT_U7_S))
+#define PCNT_PLUS_CNT_U7_V  0xFFFF
+#define PCNT_PLUS_CNT_U7_S  0
+
+#define PCNT_INT_RAW_REG          (DR_REG_PCNT_BASE + 0x0080)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_RAW : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_RAW : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_RAW : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_RAW : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_RAW : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_RAW : RO ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_RAW : RO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_RAW : RO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_S  0
+
+#define PCNT_INT_ST_REG          (DR_REG_PCNT_BASE + 0x0084)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ST : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ST  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ST : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ST  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ST : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ST  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ST  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ST : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ST  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ST : RO; bitpos: [2]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U2_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ST    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_M  (PCNT_CNT_THR_EVENT_U2_INT_ST_V << PCNT_CNT_THR_EVENT_U2_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ST : RO; bitpos: [1]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U1_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ST    (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_M  (PCNT_CNT_THR_EVENT_U1_INT_ST_V << PCNT_CNT_THR_EVENT_U1_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ST : RO; bitpos: [0]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U0_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ST    (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_M  (PCNT_CNT_THR_EVENT_U0_INT_ST_V << PCNT_CNT_THR_EVENT_U0_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_S  0
+
+/* PCNT_INT_ENA_REG register
+ * Interrupt enable register
+ */
+
+#define PCNT_INT_ENA_REG          (DR_REG_PCNT_BASE + 0x0088)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ENA : R/W ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ENA : R/W ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ENA : R/W ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ENA : R/W ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ENA : R/W ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ENA : R/W ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_S  0
+
+#define PCNT_INT_CLR_REG          (DR_REG_PCNT_BASE + 0x008c)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_CLR : WO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel7 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_CLR : WO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel6 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_CLR : WO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel5 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_CLR : WO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel4 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_CLR : WO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel3 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_CLR : WO; bitpos: [2]; default: 0;
+ * Set this bit to clear the PCNT_CNT_THR_EVENT_U2_INT interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_M  (PCNT_CNT_THR_EVENT_U2_INT_CLR_V << PCNT_CNT_THR_EVENT_U2_INT_CLR_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_CLR : WO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel1 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_CLR : WO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel0 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_S  0
+
+#define PCNT_U0_STATUS_REG          (DR_REG_PCNT_BASE + 0x0090)
+
+/* PCNT_CORE_STATUS_U0 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U0  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_M  ((PCNT_CORE_STATUS_U0_V)<<(PCNT_CORE_STATUS_U0_S))
+#define PCNT_CORE_STATUS_U0_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_S  0
+
+/* 0: positive value to zero;
+ * 1: negative value to zero;
+ * 2: counter value negative;
+ * 3: counter value positive
+ */
+
+#define PCNT_STATUS_CNT_MODE    0x3
+#define PCNT_STATUS_CNT_MODE_M  ((PCNT_STATUS_CNT_MODE_V)<<(PCNT_STATUS_CNT_MODE_S))
+#define PCNT_STATUS_CNT_MODE_V  0x3
+#define PCNT_STATUS_CNT_MODE_S  0
+
+/* counter value equals to thresh1 */
+
+#define PCNT_STATUS_THRES1    BIT(2)
+#define PCNT_STATUS_THRES1_M  BIT(2)
+#define PCNT_STATUS_THRES1_V  0x1
+#define PCNT_STATUS_THRES1_S  2
+
+/* counter value equals to thresh0 */
+
+#define PCNT_STATUS_THRES0    BIT(3)
+#define PCNT_STATUS_THRES0_M  BIT(3)
+#define PCNT_STATUS_THRES0_V  0x1
+#define PCNT_STATUS_THRES0_S  3
+
+/* counter value reaches h_lim */
+
+#define PCNT_STATUS_L_LIM    BIT(4)
+#define PCNT_STATUS_L_LIM_M  BIT(4)
+#define PCNT_STATUS_L_LIM_V  0x1
+#define PCNT_STATUS_L_LIM_S  4
+
+/* counter value reaches l_lim */
+
+#define PCNT_STATUS_H_LIM    BIT(5)
+#define PCNT_STATUS_H_LIM_M  BIT(5)
+#define PCNT_STATUS_H_LIM_V  0x1
+#define PCNT_STATUS_H_LIM_S  5
+
+/* counter value equals to zero */
+
+#define PCNT_STATUS_ZERO    BIT(6)
+#define PCNT_STATUS_ZERO_M  BIT(6)
+#define PCNT_STATUS_ZERO_V  0x1
+#define PCNT_STATUS_ZERO_S  6
+
+#define PCNT_U1_STATUS_REG          (DR_REG_PCNT_BASE + 0x0094)
+
+/* PCNT_CORE_STATUS_U1 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U1  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_M  ((PCNT_CORE_STATUS_U1_V)<<(PCNT_CORE_STATUS_U1_S))
+#define PCNT_CORE_STATUS_U1_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_S  0
+
+#define PCNT_U2_STATUS_REG          (DR_REG_PCNT_BASE + 0x0098)
+
+/* PCNT_CORE_STATUS_U2 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U2  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_M  ((PCNT_CORE_STATUS_U2_V)<<(PCNT_CORE_STATUS_U2_S))
+#define PCNT_CORE_STATUS_U2_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_S  0
+
+#define PCNT_U3_STATUS_REG          (DR_REG_PCNT_BASE + 0x009c)
+
+/* PCNT_CORE_STATUS_U3 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U3  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_M  ((PCNT_CORE_STATUS_U3_V)<<(PCNT_CORE_STATUS_U3_S))
+#define PCNT_CORE_STATUS_U3_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_S  0
+
+#define PCNT_U4_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a0)
+/* PCNT_CORE_STATUS_U4 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U4  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_M  ((PCNT_CORE_STATUS_U4_V)<<(PCNT_CORE_STATUS_U4_S))
+#define PCNT_CORE_STATUS_U4_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_S  0
+
+#define PCNT_U5_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a4)
+/* PCNT_CORE_STATUS_U5 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U5  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_M  ((PCNT_CORE_STATUS_U5_V)<<(PCNT_CORE_STATUS_U5_S))
+#define PCNT_CORE_STATUS_U5_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_S  0
+
+#define PCNT_U6_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a8)
+/* PCNT_CORE_STATUS_U6 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U6  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_M  ((PCNT_CORE_STATUS_U6_V)<<(PCNT_CORE_STATUS_U6_S))
+#define PCNT_CORE_STATUS_U6_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_S  0
+
+#define PCNT_U7_STATUS_REG          (DR_REG_PCNT_BASE + 0x00ac)
+
+/* PCNT_CORE_STATUS_U7 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U7  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_M  ((PCNT_CORE_STATUS_U7_V)<<(PCNT_CORE_STATUS_U7_S))
+#define PCNT_CORE_STATUS_U7_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_S  0
+
+#define PCNT_CTRL_REG          (DR_REG_PCNT_BASE + 0x00b0)
+
+/* PCNT_CLK_EN : R/W ;bitpos:[16] ;default: 1'b0 ; */
+
+#define PCNT_CLK_EN  (BIT(16))
+#define PCNT_CLK_EN_M  (BIT(16))
+#define PCNT_CLK_EN_V  0x1
+#define PCNT_CLK_EN_S  16
+
+/* PCNT_CNT_PAUSE_U7 : R/W ;bitpos:[15] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit7's counter. */
+
+#define PCNT_CNT_PAUSE_U7  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_M  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_V  0x1
+#define PCNT_CNT_PAUSE_U7_S  15
+
+/* PCNT_PLUS_CNT_RST_U7 : R/W ;bitpos:[14] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit7's counter. */
+
+#define PCNT_PLUS_CNT_RST_U7  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_M  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_V  0x1
+#define PCNT_PLUS_CNT_RST_U7_S  14
+
+/* PCNT_CNT_PAUSE_U6 : R/W ;bitpos:[13] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit6's counter. */
+
+#define PCNT_CNT_PAUSE_U6  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_M  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_V  0x1
+#define PCNT_CNT_PAUSE_U6_S  13
+
+/* PCNT_PLUS_CNT_RST_U6 : R/W ;bitpos:[12] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit6's counter. */
+
+#define PCNT_PLUS_CNT_RST_U6  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_M  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_V  0x1
+#define PCNT_PLUS_CNT_RST_U6_S  12
+
+/* PCNT_CNT_PAUSE_U5 : R/W ;bitpos:[11] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit5's counter. */
+
+#define PCNT_CNT_PAUSE_U5  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_M  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_V  0x1
+#define PCNT_CNT_PAUSE_U5_S  11
+
+/* PCNT_PLUS_CNT_RST_U5 : R/W ;bitpos:[10] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit5's counter. */
+
+#define PCNT_PLUS_CNT_RST_U5  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_M  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_V  0x1
+#define PCNT_PLUS_CNT_RST_U5_S  10
+
+/* PCNT_CNT_PAUSE_U4 : R/W ;bitpos:[9] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit4's counter. */
+
+#define PCNT_CNT_PAUSE_U4  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_M  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_V  0x1
+#define PCNT_CNT_PAUSE_U4_S  9
+
+/* PCNT_PLUS_CNT_RST_U4 : R/W ;bitpos:[8] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit4's counter. */
+
+#define PCNT_PLUS_CNT_RST_U4  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_M  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_V  0x1
+#define PCNT_PLUS_CNT_RST_U4_S  8
+
+/* PCNT_CNT_PAUSE_U3 : R/W ;bitpos:[7] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit3's counter. */
+
+#define PCNT_CNT_PAUSE_U3  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_M  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_V  0x1
+#define PCNT_CNT_PAUSE_U3_S  7
+
+/* PCNT_PLUS_CNT_RST_U3 : R/W ;bitpos:[6] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit3's counter. */
+
+#define PCNT_PLUS_CNT_RST_U3  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_M  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_V  0x1
+#define PCNT_PLUS_CNT_RST_U3_S  6
+
+/* PCNT_CNT_PAUSE_U2 : R/W ;bitpos:[5] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit2's counter. */
+
+#define PCNT_CNT_PAUSE_U2  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_M  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_V  0x1
+#define PCNT_CNT_PAUSE_U2_S  5
+
+/* PCNT_PLUS_CNT_RST_U2 : R/W ;bitpos:[4] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit2's counter. */
+
+#define PCNT_PLUS_CNT_RST_U2  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_M  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_V  0x1
+#define PCNT_PLUS_CNT_RST_U2_S  4
+
+/* PCNT_CNT_PAUSE_U1 : R/W ;bitpos:[3] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit1's counter. */
+
+#define PCNT_CNT_PAUSE_U1  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_M  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_V  0x1
+#define PCNT_CNT_PAUSE_U1_S  3
+
+/* PCNT_PLUS_CNT_RST_U1 : R/W ;bitpos:[2] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit1's counter. */
+
+#define PCNT_PLUS_CNT_RST_U1  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_M  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_V  0x1
+#define PCNT_PLUS_CNT_RST_U1_S  2
+
+/* PCNT_CNT_PAUSE_U0 : R/W ;bitpos:[1] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit0's counter. */
+
+#define PCNT_CNT_PAUSE_U0  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_M  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_V  0x1
+#define PCNT_CNT_PAUSE_U0_S  1
+
+/* PCNT_PLUS_CNT_RST_U0 : R/W ;bitpos:[0] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit0's counter. */
+
+#define PCNT_PLUS_CNT_RST_U0  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_M  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_V  0x1
+#define PCNT_PLUS_CNT_RST_U0_S  0
+
+#define PCNT_DATE_REG          (DR_REG_PCNT_BASE + 0x00fc)
+
+/* PCNT_DATE : R/W ;bitpos:[31:0] ;default: 32'h14122600 ; */
+
+#define PCNT_DATE    0xFFFFFFFF
+#define PCNT_DATE_M  ((PCNT_DATE_V)<<(PCNT_DATE_S))
+#define PCNT_DATE_V  0xFFFFFFFF
+#define PCNT_DATE_S  0
+
+/* Index macros for CONF0/1/2 */
+
+#define PCNT_CONF0_U(X)   PCNT_U0_CONF0_REG + (X * 12)
+#define PCNT_CONF1_U(X)   PCNT_U0_CONF1_REG + (X * 12)
+#define PCNT_CONF2_U(X)   PCNT_U0_CONF2_REG + (X * 12)
+
+/* Index macros for CONT */
+
+#define PCNT_CNT_U(X)     PCNT_U0_CNT_REG + (X * 4)

Review Comment:
   ```suggestion
   #define PCNT_CNT_U(X)     PCNT_U0_CNT_REG + ((X) * 4)
   ```



##########
arch/xtensa/src/esp32/hardware/esp32_pcnt.h:
##########
@@ -0,0 +1,2495 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/hardware/esp32_pcnt.h
+ *
+ * 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_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+#define __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* PCNT_U0_CONF0_REG register
+ * Configuration register 0 for unit 0
+ */
+
+#define PCNT_U0_CONF0_REG (DR_REG_PCNT_BASE + 0x0)
+
+/* PCNT_CH1_LCTRL_MODE_U0 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_M  (PCNT_CH1_LCTRL_MODE_U0_V << PCNT_CH1_LCTRL_MODE_U0_S)
+#define PCNT_CH1_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U0 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_M  (PCNT_CH1_HCTRL_MODE_U0_V << PCNT_CH1_HCTRL_MODE_U0_S)
+#define PCNT_CH1_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_S  28
+
+/* PCNT_CH1_POS_MODE_U0 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U0    0x00000003
+#define PCNT_CH1_POS_MODE_U0_M  (PCNT_CH1_POS_MODE_U0_V << PCNT_CH1_POS_MODE_U0_S)
+#define PCNT_CH1_POS_MODE_U0_V  0x00000003
+#define PCNT_CH1_POS_MODE_U0_S  26
+
+/* PCNT_CH1_NEG_MODE_U0 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U0    0x00000003
+#define PCNT_CH1_NEG_MODE_U0_M  (PCNT_CH1_NEG_MODE_U0_V << PCNT_CH1_NEG_MODE_U0_S)
+#define PCNT_CH1_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U0_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U0 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_M  (PCNT_CH0_LCTRL_MODE_U0_V << PCNT_CH0_LCTRL_MODE_U0_S)
+#define PCNT_CH0_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U0 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_M  (PCNT_CH0_HCTRL_MODE_U0_V << PCNT_CH0_HCTRL_MODE_U0_S)
+#define PCNT_CH0_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_S  20
+
+/* PCNT_CH0_POS_MODE_U0 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U0    0x00000003
+#define PCNT_CH0_POS_MODE_U0_M  (PCNT_CH0_POS_MODE_U0_V << PCNT_CH0_POS_MODE_U0_S)
+#define PCNT_CH0_POS_MODE_U0_V  0x00000003
+#define PCNT_CH0_POS_MODE_U0_S  18
+
+/* PCNT_CH0_NEG_MODE_U0 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U0    0x00000003
+#define PCNT_CH0_NEG_MODE_U0_M  (PCNT_CH0_NEG_MODE_U0_V << PCNT_CH0_NEG_MODE_U0_S)
+#define PCNT_CH0_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U0_S  16
+
+/* PCNT_THR_THRES1_EN_U0 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 0's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U0    (BIT(15))
+#define PCNT_THR_THRES1_EN_U0_M  (PCNT_THR_THRES1_EN_U0_V << PCNT_THR_THRES1_EN_U0_S)
+#define PCNT_THR_THRES1_EN_U0_V  0x00000001
+#define PCNT_THR_THRES1_EN_U0_S  15
+
+/* PCNT_THR_THRES0_EN_U0 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 0's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U0    (BIT(14))
+#define PCNT_THR_THRES0_EN_U0_M  (PCNT_THR_THRES0_EN_U0_V << PCNT_THR_THRES0_EN_U0_S)
+#define PCNT_THR_THRES0_EN_U0_V  0x00000001
+#define PCNT_THR_THRES0_EN_U0_S  14
+
+/* PCNT_THR_L_LIM_EN_U0 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 0's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U0    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U0_M  (PCNT_THR_L_LIM_EN_U0_V << PCNT_THR_L_LIM_EN_U0_S)
+#define PCNT_THR_L_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U0_S  13
+
+/* PCNT_THR_H_LIM_EN_U0 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 0's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U0    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U0_M  (PCNT_THR_H_LIM_EN_U0_V << PCNT_THR_H_LIM_EN_U0_S)
+#define PCNT_THR_H_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U0_S  12
+
+/* PCNT_THR_ZERO_EN_U0 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 0's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U0    (BIT(11))
+#define PCNT_THR_ZERO_EN_U0_M  (PCNT_THR_ZERO_EN_U0_V << PCNT_THR_ZERO_EN_U0_S)
+#define PCNT_THR_ZERO_EN_U0_V  0x00000001
+#define PCNT_THR_ZERO_EN_U0_S  11
+
+/* PCNT_FILTER_EN_U0 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 0's input filter.
+ */
+
+#define PCNT_FILTER_EN_U0    (BIT(10))
+#define PCNT_FILTER_EN_U0_M  (PCNT_FILTER_EN_U0_V << PCNT_FILTER_EN_U0_S)
+#define PCNT_FILTER_EN_U0_V  0x00000001
+#define PCNT_FILTER_EN_U0_S  10
+
+/* PCNT_FILTER_THRES_U0 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U0    0x000003ff
+#define PCNT_FILTER_THRES_U0_M  (PCNT_FILTER_THRES_U0_V << PCNT_FILTER_THRES_U0_S)
+#define PCNT_FILTER_THRES_U0_V  0x000003ff
+#define PCNT_FILTER_THRES_U0_S  0
+
+/* PCNT_U0_CONF1_REG register
+ * Configuration register 1 for unit 0
+ */
+
+#define PCNT_U0_CONF1_REG (DR_REG_PCNT_BASE + 0x4)
+
+/* PCNT_CNT_THRES1_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES1_U0    0x0000ffff
+#define PCNT_CNT_THRES1_U0_M  (PCNT_CNT_THRES1_U0_V << PCNT_CNT_THRES1_U0_S)
+#define PCNT_CNT_THRES1_U0_V  0x0000ffff
+#define PCNT_CNT_THRES1_U0_S  16
+
+/* PCNT_CNT_THRES0_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES0_U0    0x0000ffff
+#define PCNT_CNT_THRES0_U0_M  (PCNT_CNT_THRES0_U0_V << PCNT_CNT_THRES0_U0_S)
+#define PCNT_CNT_THRES0_U0_V  0x0000ffff
+#define PCNT_CNT_THRES0_U0_S  0
+
+/* PCNT_U0_CONF2_REG register
+ * Configuration register 2 for unit 0
+ */
+
+#define PCNT_U0_CONF2_REG (DR_REG_PCNT_BASE + 0x8)
+
+/* PCNT_CNT_L_LIM_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 0.
+ */
+
+#define PCNT_CNT_L_LIM_U0    0x0000ffff
+#define PCNT_CNT_L_LIM_U0_M  (PCNT_CNT_L_LIM_U0_V << PCNT_CNT_L_LIM_U0_S)
+#define PCNT_CNT_L_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U0_S  16
+
+/* PCNT_CNT_H_LIM_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 0.
+ */
+
+#define PCNT_CNT_H_LIM_U0    0x0000ffff
+#define PCNT_CNT_H_LIM_U0_M  (PCNT_CNT_H_LIM_U0_V << PCNT_CNT_H_LIM_U0_S)
+#define PCNT_CNT_H_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U0_S  0
+
+/* PCNT_U1_CONF0_REG register
+ * Configuration register 0 for unit 1
+ */
+
+#define PCNT_U1_CONF0_REG (DR_REG_PCNT_BASE + 0xc)
+
+/* PCNT_CH1_LCTRL_MODE_U1 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_M  (PCNT_CH1_LCTRL_MODE_U1_V << PCNT_CH1_LCTRL_MODE_U1_S)
+#define PCNT_CH1_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U1 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_M  (PCNT_CH1_HCTRL_MODE_U1_V << PCNT_CH1_HCTRL_MODE_U1_S)
+#define PCNT_CH1_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_S  28
+
+/* PCNT_CH1_POS_MODE_U1 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U1    0x00000003
+#define PCNT_CH1_POS_MODE_U1_M  (PCNT_CH1_POS_MODE_U1_V << PCNT_CH1_POS_MODE_U1_S)
+#define PCNT_CH1_POS_MODE_U1_V  0x00000003
+#define PCNT_CH1_POS_MODE_U1_S  26
+
+/* PCNT_CH1_NEG_MODE_U1 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U1    0x00000003
+#define PCNT_CH1_NEG_MODE_U1_M  (PCNT_CH1_NEG_MODE_U1_V << PCNT_CH1_NEG_MODE_U1_S)
+#define PCNT_CH1_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U1_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U1 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_M  (PCNT_CH0_LCTRL_MODE_U1_V << PCNT_CH0_LCTRL_MODE_U1_S)
+#define PCNT_CH0_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U1 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_M  (PCNT_CH0_HCTRL_MODE_U1_V << PCNT_CH0_HCTRL_MODE_U1_S)
+#define PCNT_CH0_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_S  20
+
+/* PCNT_CH0_POS_MODE_U1 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U1    0x00000003
+#define PCNT_CH0_POS_MODE_U1_M  (PCNT_CH0_POS_MODE_U1_V << PCNT_CH0_POS_MODE_U1_S)
+#define PCNT_CH0_POS_MODE_U1_V  0x00000003
+#define PCNT_CH0_POS_MODE_U1_S  18
+
+/* PCNT_CH0_NEG_MODE_U1 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U1    0x00000003
+#define PCNT_CH0_NEG_MODE_U1_M  (PCNT_CH0_NEG_MODE_U1_V << PCNT_CH0_NEG_MODE_U1_S)
+#define PCNT_CH0_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U1_S  16
+
+/* PCNT_THR_THRES1_EN_U1 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 1's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U1    (BIT(15))
+#define PCNT_THR_THRES1_EN_U1_M  (PCNT_THR_THRES1_EN_U1_V << PCNT_THR_THRES1_EN_U1_S)
+#define PCNT_THR_THRES1_EN_U1_V  0x00000001
+#define PCNT_THR_THRES1_EN_U1_S  15
+
+/* PCNT_THR_THRES0_EN_U1 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 1's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U1    (BIT(14))
+#define PCNT_THR_THRES0_EN_U1_M  (PCNT_THR_THRES0_EN_U1_V << PCNT_THR_THRES0_EN_U1_S)
+#define PCNT_THR_THRES0_EN_U1_V  0x00000001
+#define PCNT_THR_THRES0_EN_U1_S  14
+
+/* PCNT_THR_L_LIM_EN_U1 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 1's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U1    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U1_M  (PCNT_THR_L_LIM_EN_U1_V << PCNT_THR_L_LIM_EN_U1_S)
+#define PCNT_THR_L_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U1_S  13
+
+/* PCNT_THR_H_LIM_EN_U1 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 1's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U1    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U1_M  (PCNT_THR_H_LIM_EN_U1_V << PCNT_THR_H_LIM_EN_U1_S)
+#define PCNT_THR_H_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U1_S  12
+
+/* PCNT_THR_ZERO_EN_U1 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 1's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U1    (BIT(11))
+#define PCNT_THR_ZERO_EN_U1_M  (PCNT_THR_ZERO_EN_U1_V << PCNT_THR_ZERO_EN_U1_S)
+#define PCNT_THR_ZERO_EN_U1_V  0x00000001
+#define PCNT_THR_ZERO_EN_U1_S  11
+
+/* PCNT_FILTER_EN_U1 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 1's input filter.
+ */
+
+#define PCNT_FILTER_EN_U1    (BIT(10))
+#define PCNT_FILTER_EN_U1_M  (PCNT_FILTER_EN_U1_V << PCNT_FILTER_EN_U1_S)
+#define PCNT_FILTER_EN_U1_V  0x00000001
+#define PCNT_FILTER_EN_U1_S  10
+
+/* PCNT_FILTER_THRES_U1 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U1    0x000003ff
+#define PCNT_FILTER_THRES_U1_M  (PCNT_FILTER_THRES_U1_V << PCNT_FILTER_THRES_U1_S)
+#define PCNT_FILTER_THRES_U1_V  0x000003ff
+#define PCNT_FILTER_THRES_U1_S  0
+
+/* PCNT_U1_CONF1_REG register
+ * Configuration register 1 for unit 1
+ */
+
+#define PCNT_U1_CONF1_REG (DR_REG_PCNT_BASE + 0x10)
+
+/* PCNT_CNT_THRES1_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES1_U1    0x0000ffff
+#define PCNT_CNT_THRES1_U1_M  (PCNT_CNT_THRES1_U1_V << PCNT_CNT_THRES1_U1_S)
+#define PCNT_CNT_THRES1_U1_V  0x0000ffff
+#define PCNT_CNT_THRES1_U1_S  16
+
+/* PCNT_CNT_THRES0_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES0_U1    0x0000ffff
+#define PCNT_CNT_THRES0_U1_M  (PCNT_CNT_THRES0_U1_V << PCNT_CNT_THRES0_U1_S)
+#define PCNT_CNT_THRES0_U1_V  0x0000ffff
+#define PCNT_CNT_THRES0_U1_S  0
+
+/* PCNT_U1_CONF2_REG register
+ * Configuration register 2 for unit 1
+ */
+
+#define PCNT_U1_CONF2_REG (DR_REG_PCNT_BASE + 0x14)
+
+/* PCNT_CNT_L_LIM_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 1.
+ */
+
+#define PCNT_CNT_L_LIM_U1    0x0000ffff
+#define PCNT_CNT_L_LIM_U1_M  (PCNT_CNT_L_LIM_U1_V << PCNT_CNT_L_LIM_U1_S)
+#define PCNT_CNT_L_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U1_S  16
+
+/* PCNT_CNT_H_LIM_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 1.
+ */
+
+#define PCNT_CNT_H_LIM_U1    0x0000ffff
+#define PCNT_CNT_H_LIM_U1_M  (PCNT_CNT_H_LIM_U1_V << PCNT_CNT_H_LIM_U1_S)
+#define PCNT_CNT_H_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U1_S  0
+
+/* PCNT_U2_CONF0_REG register
+ * Configuration register 0 for unit 2
+ */
+
+#define PCNT_U2_CONF0_REG (DR_REG_PCNT_BASE + 0x18)
+
+/* PCNT_CH1_LCTRL_MODE_U2 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_M  (PCNT_CH1_LCTRL_MODE_U2_V << PCNT_CH1_LCTRL_MODE_U2_S)
+#define PCNT_CH1_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U2 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_M  (PCNT_CH1_HCTRL_MODE_U2_V << PCNT_CH1_HCTRL_MODE_U2_S)
+#define PCNT_CH1_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_S  28
+
+/* PCNT_CH1_POS_MODE_U2 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U2    0x00000003
+#define PCNT_CH1_POS_MODE_U2_M  (PCNT_CH1_POS_MODE_U2_V << PCNT_CH1_POS_MODE_U2_S)
+#define PCNT_CH1_POS_MODE_U2_V  0x00000003
+#define PCNT_CH1_POS_MODE_U2_S  26
+
+/* PCNT_CH1_NEG_MODE_U2 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U2    0x00000003
+#define PCNT_CH1_NEG_MODE_U2_M  (PCNT_CH1_NEG_MODE_U2_V << PCNT_CH1_NEG_MODE_U2_S)
+#define PCNT_CH1_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U2_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U2 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_M  (PCNT_CH0_LCTRL_MODE_U2_V << PCNT_CH0_LCTRL_MODE_U2_S)
+#define PCNT_CH0_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U2 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_M  (PCNT_CH0_HCTRL_MODE_U2_V << PCNT_CH0_HCTRL_MODE_U2_S)
+#define PCNT_CH0_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_S  20
+
+/* PCNT_CH0_POS_MODE_U2 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U2    0x00000003
+#define PCNT_CH0_POS_MODE_U2_M  (PCNT_CH0_POS_MODE_U2_V << PCNT_CH0_POS_MODE_U2_S)
+#define PCNT_CH0_POS_MODE_U2_V  0x00000003
+#define PCNT_CH0_POS_MODE_U2_S  18
+
+/* PCNT_CH0_NEG_MODE_U2 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U2    0x00000003
+#define PCNT_CH0_NEG_MODE_U2_M  (PCNT_CH0_NEG_MODE_U2_V << PCNT_CH0_NEG_MODE_U2_S)
+#define PCNT_CH0_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U2_S  16
+
+/* PCNT_THR_THRES1_EN_U2 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 2's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U2    (BIT(15))
+#define PCNT_THR_THRES1_EN_U2_M  (PCNT_THR_THRES1_EN_U2_V << PCNT_THR_THRES1_EN_U2_S)
+#define PCNT_THR_THRES1_EN_U2_V  0x00000001
+#define PCNT_THR_THRES1_EN_U2_S  15
+
+/* PCNT_THR_THRES0_EN_U2 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 2's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U2    (BIT(14))
+#define PCNT_THR_THRES0_EN_U2_M  (PCNT_THR_THRES0_EN_U2_V << PCNT_THR_THRES0_EN_U2_S)
+#define PCNT_THR_THRES0_EN_U2_V  0x00000001
+#define PCNT_THR_THRES0_EN_U2_S  14
+
+/* PCNT_THR_L_LIM_EN_U2 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 2's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U2    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U2_M  (PCNT_THR_L_LIM_EN_U2_V << PCNT_THR_L_LIM_EN_U2_S)
+#define PCNT_THR_L_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U2_S  13
+
+/* PCNT_THR_H_LIM_EN_U2 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 2's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U2    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U2_M  (PCNT_THR_H_LIM_EN_U2_V << PCNT_THR_H_LIM_EN_U2_S)
+#define PCNT_THR_H_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U2_S  12
+
+/* PCNT_THR_ZERO_EN_U2 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 2's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U2    (BIT(11))
+#define PCNT_THR_ZERO_EN_U2_M  (PCNT_THR_ZERO_EN_U2_V << PCNT_THR_ZERO_EN_U2_S)
+#define PCNT_THR_ZERO_EN_U2_V  0x00000001
+#define PCNT_THR_ZERO_EN_U2_S  11
+
+/* PCNT_FILTER_EN_U2 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 2's input filter.
+ */
+
+#define PCNT_FILTER_EN_U2    (BIT(10))
+#define PCNT_FILTER_EN_U2_M  (PCNT_FILTER_EN_U2_V << PCNT_FILTER_EN_U2_S)
+#define PCNT_FILTER_EN_U2_V  0x00000001
+#define PCNT_FILTER_EN_U2_S  10
+
+/* PCNT_FILTER_THRES_U2 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U2    0x000003ff
+#define PCNT_FILTER_THRES_U2_M  (PCNT_FILTER_THRES_U2_V << PCNT_FILTER_THRES_U2_S)
+#define PCNT_FILTER_THRES_U2_V  0x000003ff
+#define PCNT_FILTER_THRES_U2_S  0
+
+/* PCNT_U2_CONF1_REG register
+ * Configuration register 1 for unit 2
+ */
+
+#define PCNT_U2_CONF1_REG (DR_REG_PCNT_BASE + 0x1c)
+
+/* PCNT_CNT_THRES1_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES1_U2    0x0000ffff
+#define PCNT_CNT_THRES1_U2_M  (PCNT_CNT_THRES1_U2_V << PCNT_CNT_THRES1_U2_S)
+#define PCNT_CNT_THRES1_U2_V  0x0000ffff
+#define PCNT_CNT_THRES1_U2_S  16
+
+/* PCNT_CNT_THRES0_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES0_U2    0x0000ffff
+#define PCNT_CNT_THRES0_U2_M  (PCNT_CNT_THRES0_U2_V << PCNT_CNT_THRES0_U2_S)
+#define PCNT_CNT_THRES0_U2_V  0x0000ffff
+#define PCNT_CNT_THRES0_U2_S  0
+
+/* PCNT_U2_CONF2_REG register
+ * Configuration register 2 for unit 2
+ */
+
+#define PCNT_U2_CONF2_REG (DR_REG_PCNT_BASE + 0x20)
+
+/* PCNT_CNT_L_LIM_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 2.
+ */
+
+#define PCNT_CNT_L_LIM_U2    0x0000ffff
+#define PCNT_CNT_L_LIM_U2_M  (PCNT_CNT_L_LIM_U2_V << PCNT_CNT_L_LIM_U2_S)
+#define PCNT_CNT_L_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U2_S  16
+
+/* PCNT_CNT_H_LIM_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 2.
+ */
+
+#define PCNT_CNT_H_LIM_U2    0x0000ffff
+#define PCNT_CNT_H_LIM_U2_M  (PCNT_CNT_H_LIM_U2_V << PCNT_CNT_H_LIM_U2_S)
+#define PCNT_CNT_H_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U2_S  0
+
+/* PCNT_U3_CONF0_REG register
+ * Configuration register 0 for unit 3
+ */
+
+#define PCNT_U3_CONF0_REG (DR_REG_PCNT_BASE + 0x24)
+
+/* PCNT_CH1_LCTRL_MODE_U3 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_M  (PCNT_CH1_LCTRL_MODE_U3_V << PCNT_CH1_LCTRL_MODE_U3_S)
+#define PCNT_CH1_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U3 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_M  (PCNT_CH1_HCTRL_MODE_U3_V << PCNT_CH1_HCTRL_MODE_U3_S)
+#define PCNT_CH1_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_S  28
+
+/* PCNT_CH1_POS_MODE_U3 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U3    0x00000003
+#define PCNT_CH1_POS_MODE_U3_M  (PCNT_CH1_POS_MODE_U3_V << PCNT_CH1_POS_MODE_U3_S)
+#define PCNT_CH1_POS_MODE_U3_V  0x00000003
+#define PCNT_CH1_POS_MODE_U3_S  26
+
+/* PCNT_CH1_NEG_MODE_U3 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U3    0x00000003
+#define PCNT_CH1_NEG_MODE_U3_M  (PCNT_CH1_NEG_MODE_U3_V << PCNT_CH1_NEG_MODE_U3_S)
+#define PCNT_CH1_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U3_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U3 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_M  (PCNT_CH0_LCTRL_MODE_U3_V << PCNT_CH0_LCTRL_MODE_U3_S)
+#define PCNT_CH0_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U3 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_M  (PCNT_CH0_HCTRL_MODE_U3_V << PCNT_CH0_HCTRL_MODE_U3_S)
+#define PCNT_CH0_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_S  20
+
+/* PCNT_CH0_POS_MODE_U3 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U3    0x00000003
+#define PCNT_CH0_POS_MODE_U3_M  (PCNT_CH0_POS_MODE_U3_V << PCNT_CH0_POS_MODE_U3_S)
+#define PCNT_CH0_POS_MODE_U3_V  0x00000003
+#define PCNT_CH0_POS_MODE_U3_S  18
+
+/* PCNT_CH0_NEG_MODE_U3 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U3    0x00000003
+#define PCNT_CH0_NEG_MODE_U3_M  (PCNT_CH0_NEG_MODE_U3_V << PCNT_CH0_NEG_MODE_U3_S)
+#define PCNT_CH0_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U3_S  16
+
+/* PCNT_THR_THRES1_EN_U3 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 3's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U3    (BIT(15))
+#define PCNT_THR_THRES1_EN_U3_M  (PCNT_THR_THRES1_EN_U3_V << PCNT_THR_THRES1_EN_U3_S)
+#define PCNT_THR_THRES1_EN_U3_V  0x00000001
+#define PCNT_THR_THRES1_EN_U3_S  15
+
+/* PCNT_THR_THRES0_EN_U3 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 3's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U3    (BIT(14))
+#define PCNT_THR_THRES0_EN_U3_M  (PCNT_THR_THRES0_EN_U3_V << PCNT_THR_THRES0_EN_U3_S)
+#define PCNT_THR_THRES0_EN_U3_V  0x00000001
+#define PCNT_THR_THRES0_EN_U3_S  14
+
+/* PCNT_THR_L_LIM_EN_U3 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 3's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U3    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U3_M  (PCNT_THR_L_LIM_EN_U3_V << PCNT_THR_L_LIM_EN_U3_S)
+#define PCNT_THR_L_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U3_S  13
+
+/* PCNT_THR_H_LIM_EN_U3 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 3's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U3    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U3_M  (PCNT_THR_H_LIM_EN_U3_V << PCNT_THR_H_LIM_EN_U3_S)
+#define PCNT_THR_H_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U3_S  12
+
+/* PCNT_THR_ZERO_EN_U3 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 3's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U3    (BIT(11))
+#define PCNT_THR_ZERO_EN_U3_M  (PCNT_THR_ZERO_EN_U3_V << PCNT_THR_ZERO_EN_U3_S)
+#define PCNT_THR_ZERO_EN_U3_V  0x00000001
+#define PCNT_THR_ZERO_EN_U3_S  11
+
+/* PCNT_FILTER_EN_U3 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 3's input filter.
+ */
+
+#define PCNT_FILTER_EN_U3    (BIT(10))
+#define PCNT_FILTER_EN_U3_M  (PCNT_FILTER_EN_U3_V << PCNT_FILTER_EN_U3_S)
+#define PCNT_FILTER_EN_U3_V  0x00000001
+#define PCNT_FILTER_EN_U3_S  10
+
+/* PCNT_FILTER_THRES_U3 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U3    0x000003ff
+#define PCNT_FILTER_THRES_U3_M  (PCNT_FILTER_THRES_U3_V << PCNT_FILTER_THRES_U3_S)
+#define PCNT_FILTER_THRES_U3_V  0x000003ff
+#define PCNT_FILTER_THRES_U3_S  0
+
+/* PCNT_U3_CONF1_REG register
+ * Configuration register 1 for unit 3
+ */
+
+#define PCNT_U3_CONF1_REG (DR_REG_PCNT_BASE + 0x28)
+
+/* PCNT_CNT_THRES1_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES1_U3    0x0000ffff
+#define PCNT_CNT_THRES1_U3_M  (PCNT_CNT_THRES1_U3_V << PCNT_CNT_THRES1_U3_S)
+#define PCNT_CNT_THRES1_U3_V  0x0000ffff
+#define PCNT_CNT_THRES1_U3_S  16
+
+/* PCNT_CNT_THRES0_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES0_U3    0x0000ffff
+#define PCNT_CNT_THRES0_U3_M  (PCNT_CNT_THRES0_U3_V << PCNT_CNT_THRES0_U3_S)
+#define PCNT_CNT_THRES0_U3_V  0x0000ffff
+#define PCNT_CNT_THRES0_U3_S  0
+
+/* PCNT_U3_CONF2_REG register
+ * Configuration register 2 for unit 3
+ */
+
+#define PCNT_U3_CONF2_REG (DR_REG_PCNT_BASE + 0x2c)
+
+/* PCNT_CNT_L_LIM_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 3.
+ */
+
+#define PCNT_CNT_L_LIM_U3    0x0000ffff
+#define PCNT_CNT_L_LIM_U3_M  (PCNT_CNT_L_LIM_U3_V << PCNT_CNT_L_LIM_U3_S)
+#define PCNT_CNT_L_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U3_S  16
+
+/* PCNT_CNT_H_LIM_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 3.
+ */
+
+#define PCNT_CNT_H_LIM_U3    0x0000ffff
+#define PCNT_CNT_H_LIM_U3_M  (PCNT_CNT_H_LIM_U3_V << PCNT_CNT_H_LIM_U3_S)
+#define PCNT_CNT_H_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U3_S  0
+
+#define PCNT_U4_CONF0_REG          (DR_REG_PCNT_BASE + 0x0030)
+
+/* PCNT_CH1_LCTRL_MODE_U4 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U4_M  ((PCNT_CH1_LCTRL_MODE_U4_V)<<(PCNT_CH1_LCTRL_MODE_U4_S))
+#define PCNT_CH1_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U4_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U4 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U4_M  ((PCNT_CH1_HCTRL_MODE_U4_V)<<(PCNT_CH1_HCTRL_MODE_U4_S))
+#define PCNT_CH1_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U4_S  28
+
+/* PCNT_CH1_POS_MODE_U4 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U4  0x00000003
+#define PCNT_CH1_POS_MODE_U4_M  ((PCNT_CH1_POS_MODE_U4_V)<<(PCNT_CH1_POS_MODE_U4_S))
+#define PCNT_CH1_POS_MODE_U4_V  0x3
+#define PCNT_CH1_POS_MODE_U4_S  26
+
+/* PCNT_CH1_NEG_MODE_U4 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U4  0x00000003
+#define PCNT_CH1_NEG_MODE_U4_M  ((PCNT_CH1_NEG_MODE_U4_V)<<(PCNT_CH1_NEG_MODE_U4_S))
+#define PCNT_CH1_NEG_MODE_U4_V  0x3
+#define PCNT_CH1_NEG_MODE_U4_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U4 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U4_M  ((PCNT_CH0_LCTRL_MODE_U4_V)<<(PCNT_CH0_LCTRL_MODE_U4_S))
+#define PCNT_CH0_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U4_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U4 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U4_M  ((PCNT_CH0_HCTRL_MODE_U4_V)<<(PCNT_CH0_HCTRL_MODE_U4_S))
+#define PCNT_CH0_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U4_S  20
+
+/* PCNT_CH0_POS_MODE_U4 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U4  0x00000003
+#define PCNT_CH0_POS_MODE_U4_M  ((PCNT_CH0_POS_MODE_U4_V)<<(PCNT_CH0_POS_MODE_U4_S))
+#define PCNT_CH0_POS_MODE_U4_V  0x3
+#define PCNT_CH0_POS_MODE_U4_S  18
+
+/* PCNT_CH0_NEG_MODE_U4 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U4  0x00000003
+#define PCNT_CH0_NEG_MODE_U4_M  ((PCNT_CH0_NEG_MODE_U4_V)<<(PCNT_CH0_NEG_MODE_U4_S))
+#define PCNT_CH0_NEG_MODE_U4_V  0x3
+#define PCNT_CH0_NEG_MODE_U4_S  16
+
+/* PCNT_THR_THRES1_EN_U4 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U4  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_V  0x1
+#define PCNT_THR_THRES1_EN_U4_S  15
+
+/* PCNT_THR_THRES0_EN_U4 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U4  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_V  0x1
+#define PCNT_THR_THRES0_EN_U4_S  14
+
+/* PCNT_THR_L_LIM_EN_U4 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_l_lim  value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U4  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_V  0x1
+#define PCNT_THR_L_LIM_EN_U4_S  13
+
+/* PCNT_THR_H_LIM_EN_U4 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U4  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_V  0x1
+#define PCNT_THR_H_LIM_EN_U4_S  12
+
+/* PCNT_THR_ZERO_EN_U4 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U4  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_V  0x1
+#define PCNT_THR_ZERO_EN_U4_S  11
+
+/* PCNT_FILTER_EN_U4 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit4.
+ */
+
+#define PCNT_FILTER_EN_U4  (BIT(10))
+#define PCNT_FILTER_EN_U4_M  (BIT(10))
+#define PCNT_FILTER_EN_U4_V  0x1
+#define PCNT_FILTER_EN_U4_S  10
+
+/* PCNT_FILTER_THRES_U4 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit4.
+ */
+
+#define PCNT_FILTER_THRES_U4  0x000003FF
+#define PCNT_FILTER_THRES_U4_M  ((PCNT_FILTER_THRES_U4_V)<<(PCNT_FILTER_THRES_U4_S))
+#define PCNT_FILTER_THRES_U4_V  0x3FF
+#define PCNT_FILTER_THRES_U4_S  0
+
+#define PCNT_U4_CONF1_REG          (DR_REG_PCNT_BASE + 0x0034)
+
+/* PCNT_CNT_THRES1_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure thres1 value for unit4.
+ */
+
+#define PCNT_CNT_THRES1_U4  0x0000FFFF
+#define PCNT_CNT_THRES1_U4_M  ((PCNT_CNT_THRES1_U4_V)<<(PCNT_CNT_THRES1_U4_S))
+#define PCNT_CNT_THRES1_U4_V  0xFFFF
+#define PCNT_CNT_THRES1_U4_S  16
+
+/* PCNT_CNT_THRES0_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit4.
+ */
+
+#define PCNT_CNT_THRES0_U4  0x0000FFFF
+#define PCNT_CNT_THRES0_U4_M  ((PCNT_CNT_THRES0_U4_V)<<(PCNT_CNT_THRES0_U4_S))
+#define PCNT_CNT_THRES0_U4_V  0xFFFF
+#define PCNT_CNT_THRES0_U4_S  0
+
+#define PCNT_U4_CONF2_REG          (DR_REG_PCNT_BASE + 0x0038)
+
+/* PCNT_CNT_L_LIM_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit4.
+ */
+
+#define PCNT_CNT_L_LIM_U4  0x0000FFFF
+#define PCNT_CNT_L_LIM_U4_M  ((PCNT_CNT_L_LIM_U4_V)<<(PCNT_CNT_L_LIM_U4_S))
+#define PCNT_CNT_L_LIM_U4_V  0xFFFF
+#define PCNT_CNT_L_LIM_U4_S  16
+
+/* PCNT_CNT_H_LIM_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit4.
+ */
+
+#define PCNT_CNT_H_LIM_U4  0x0000FFFF
+#define PCNT_CNT_H_LIM_U4_M  ((PCNT_CNT_H_LIM_U4_V)<<(PCNT_CNT_H_LIM_U4_S))
+#define PCNT_CNT_H_LIM_U4_V  0xFFFF
+#define PCNT_CNT_H_LIM_U4_S  0
+
+#define PCNT_U5_CONF0_REG          (DR_REG_PCNT_BASE + 0x003c)
+
+/* PCNT_CH1_LCTRL_MODE_U5 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U5_M  ((PCNT_CH1_LCTRL_MODE_U5_V)<<(PCNT_CH1_LCTRL_MODE_U5_S))
+#define PCNT_CH1_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U5_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U5 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U5_M  ((PCNT_CH1_HCTRL_MODE_U5_V)<<(PCNT_CH1_HCTRL_MODE_U5_S))
+#define PCNT_CH1_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U5_S  28
+
+/* PCNT_CH1_POS_MODE_U5 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U5  0x00000003
+#define PCNT_CH1_POS_MODE_U5_M  ((PCNT_CH1_POS_MODE_U5_V)<<(PCNT_CH1_POS_MODE_U5_S))
+#define PCNT_CH1_POS_MODE_U5_V  0x3
+#define PCNT_CH1_POS_MODE_U5_S  26
+
+/* PCNT_CH1_NEG_MODE_U5 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U5  0x00000003
+#define PCNT_CH1_NEG_MODE_U5_M  ((PCNT_CH1_NEG_MODE_U5_V)<<(PCNT_CH1_NEG_MODE_U5_S))
+#define PCNT_CH1_NEG_MODE_U5_V  0x3
+#define PCNT_CH1_NEG_MODE_U5_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U5 : R/W ;bitpos:[23:22] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U5_M  ((PCNT_CH0_LCTRL_MODE_U5_V)<<(PCNT_CH0_LCTRL_MODE_U5_S))
+#define PCNT_CH0_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U5_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U5 : R/W ;bitpos:[21:20] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's high
+ * control signal for unit5.
+ * 0:increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U5_M  ((PCNT_CH0_HCTRL_MODE_U5_V)<<(PCNT_CH0_HCTRL_MODE_U5_S))
+#define PCNT_CH0_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U5_S  20
+
+/* PCNT_CH0_POS_MODE_U5 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U5  0x00000003
+#define PCNT_CH0_POS_MODE_U5_M  ((PCNT_CH0_POS_MODE_U5_V)<<(PCNT_CH0_POS_MODE_U5_S))
+#define PCNT_CH0_POS_MODE_U5_V  0x3
+#define PCNT_CH0_POS_MODE_U5_S  18
+
+/* PCNT_CH0_NEG_MODE_U5 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U5  0x00000003
+#define PCNT_CH0_NEG_MODE_U5_M  ((PCNT_CH0_NEG_MODE_U5_V)<<(PCNT_CH0_NEG_MODE_U5_S))
+#define PCNT_CH0_NEG_MODE_U5_V  0x3
+#define PCNT_CH0_NEG_MODE_U5_S  16
+
+/* PCNT_THR_THRES1_EN_U5 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U5  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_V  0x1
+#define PCNT_THR_THRES1_EN_U5_S  15
+
+/* PCNT_THR_THRES0_EN_U5 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U5  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_V  0x1
+#define PCNT_THR_THRES0_EN_U5_S  14
+
+/* PCNT_THR_L_LIM_EN_U5 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U5  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_V  0x1
+#define PCNT_THR_L_LIM_EN_U5_S  13
+
+/* PCNT_THR_H_LIM_EN_U5 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U5  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_V  0x1
+#define PCNT_THR_H_LIM_EN_U5_S  12
+
+/* PCNT_THR_ZERO_EN_U5 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U5  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_V  0x1
+#define PCNT_THR_ZERO_EN_U5_S  11
+
+/* PCNT_FILTER_EN_U5 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit5.
+ */
+
+#define PCNT_FILTER_EN_U5  (BIT(10))
+#define PCNT_FILTER_EN_U5_M  (BIT(10))
+#define PCNT_FILTER_EN_U5_V  0x1
+#define PCNT_FILTER_EN_U5_S  10
+
+/* PCNT_FILTER_THRES_U5 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit5.
+ */
+
+#define PCNT_FILTER_THRES_U5  0x000003FF
+#define PCNT_FILTER_THRES_U5_M  ((PCNT_FILTER_THRES_U5_V)<<(PCNT_FILTER_THRES_U5_S))
+#define PCNT_FILTER_THRES_U5_V  0x3FF
+#define PCNT_FILTER_THRES_U5_S  0
+
+#define PCNT_U5_CONF1_REG          (DR_REG_PCNT_BASE + 0x0040)
+
+/* PCNT_CNT_THRES1_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit5.
+ */
+
+#define PCNT_CNT_THRES1_U5  0x0000FFFF
+#define PCNT_CNT_THRES1_U5_M  ((PCNT_CNT_THRES1_U5_V)<<(PCNT_CNT_THRES1_U5_S))
+#define PCNT_CNT_THRES1_U5_V  0xFFFF
+#define PCNT_CNT_THRES1_U5_S  16
+
+/* PCNT_CNT_THRES0_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit5.
+ */
+
+#define PCNT_CNT_THRES0_U5  0x0000FFFF
+#define PCNT_CNT_THRES0_U5_M  ((PCNT_CNT_THRES0_U5_V)<<(PCNT_CNT_THRES0_U5_S))
+#define PCNT_CNT_THRES0_U5_V  0xFFFF
+#define PCNT_CNT_THRES0_U5_S  0
+
+#define PCNT_U5_CONF2_REG          (DR_REG_PCNT_BASE + 0x0044)
+
+/* PCNT_CNT_L_LIM_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit5.
+ */
+
+#define PCNT_CNT_L_LIM_U5  0x0000FFFF
+#define PCNT_CNT_L_LIM_U5_M  ((PCNT_CNT_L_LIM_U5_V)<<(PCNT_CNT_L_LIM_U5_S))
+#define PCNT_CNT_L_LIM_U5_V  0xFFFF
+#define PCNT_CNT_L_LIM_U5_S  16
+
+/* PCNT_CNT_H_LIM_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit5.
+ */
+
+#define PCNT_CNT_H_LIM_U5  0x0000FFFF
+#define PCNT_CNT_H_LIM_U5_M  ((PCNT_CNT_H_LIM_U5_V)<<(PCNT_CNT_H_LIM_U5_S))
+#define PCNT_CNT_H_LIM_U5_V  0xFFFF
+#define PCNT_CNT_H_LIM_U5_S  0
+
+#define PCNT_U6_CONF0_REG          (DR_REG_PCNT_BASE + 0x0048)
+
+/* PCNT_CH1_LCTRL_MODE_U6 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * low control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U6_M  ((PCNT_CH1_LCTRL_MODE_U6_V)<<(PCNT_CH1_LCTRL_MODE_U6_S))
+#define PCNT_CH1_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U6_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U6 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U6_M  ((PCNT_CH1_HCTRL_MODE_U6_V)<<(PCNT_CH1_HCTRL_MODE_U6_S))
+#define PCNT_CH1_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U6_S  28
+
+/* PCNT_CH1_POS_MODE_U6 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U6  0x00000003
+#define PCNT_CH1_POS_MODE_U6_M  ((PCNT_CH1_POS_MODE_U6_V)<<(PCNT_CH1_POS_MODE_U6_S))
+#define PCNT_CH1_POS_MODE_U6_V  0x3
+#define PCNT_CH1_POS_MODE_U6_S  26
+
+/* PCNT_CH1_NEG_MODE_U6 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * input negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U6  0x00000003
+#define PCNT_CH1_NEG_MODE_U6_M  ((PCNT_CH1_NEG_MODE_U6_V)<<(PCNT_CH1_NEG_MODE_U6_S))
+#define PCNT_CH1_NEG_MODE_U6_V  0x3
+#define PCNT_CH1_NEG_MODE_U6_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U6 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U6_M  ((PCNT_CH0_LCTRL_MODE_U6_V)<<(PCNT_CH0_LCTRL_MODE_U6_S))
+#define PCNT_CH0_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U6_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U6 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * high control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U6_M  ((PCNT_CH0_HCTRL_MODE_U6_V)<<(PCNT_CH0_HCTRL_MODE_U6_S))
+#define PCNT_CH0_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U6_S  20
+
+/* PCNT_CH0_POS_MODE_U6 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U6  0x00000003
+#define PCNT_CH0_POS_MODE_U6_M  ((PCNT_CH0_POS_MODE_U6_V)<<(PCNT_CH0_POS_MODE_U6_S))
+#define PCNT_CH0_POS_MODE_U6_V  0x3
+#define PCNT_CH0_POS_MODE_U6_S  18
+
+/* PCNT_CH0_NEG_MODE_U6 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U6  0x00000003
+#define PCNT_CH0_NEG_MODE_U6_M  ((PCNT_CH0_NEG_MODE_U6_V)<<(PCNT_CH0_NEG_MODE_U6_S))
+#define PCNT_CH0_NEG_MODE_U6_V  0x3
+#define PCNT_CH0_NEG_MODE_U6_S  16
+
+/* PCNT_THR_THRES1_EN_U6 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit6's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U6  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_V  0x1
+#define PCNT_THR_THRES1_EN_U6_S  15
+
+/* PCNT_THR_THRES0_EN_U6 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U6  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_V  0x1
+#define PCNT_THR_THRES0_EN_U6_S  14
+
+/* PCNT_THR_L_LIM_EN_U6 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U6  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_V  0x1
+#define PCNT_THR_L_LIM_EN_U6_S  13
+
+/* PCNT_THR_H_LIM_EN_U6 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit6's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U6  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_V  0x1
+#define PCNT_THR_H_LIM_EN_U6_S  12
+
+/* PCNT_THR_ZERO_EN_U6 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U6  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_V  0x1
+#define PCNT_THR_ZERO_EN_U6_S  11
+
+/* PCNT_FILTER_EN_U6 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit6.
+ */
+
+#define PCNT_FILTER_EN_U6  (BIT(10))
+#define PCNT_FILTER_EN_U6_M  (BIT(10))
+#define PCNT_FILTER_EN_U6_V  0x1
+#define PCNT_FILTER_EN_U6_S  10
+
+/* PCNT_FILTER_THRES_U6 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is
+ * smaller than this value for unit6.
+ */
+
+#define PCNT_FILTER_THRES_U6  0x000003FF
+#define PCNT_FILTER_THRES_U6_M  ((PCNT_FILTER_THRES_U6_V)<<(PCNT_FILTER_THRES_U6_S))
+#define PCNT_FILTER_THRES_U6_V  0x3FF
+#define PCNT_FILTER_THRES_U6_S  0
+
+#define PCNT_U6_CONF1_REG          (DR_REG_PCNT_BASE + 0x004c)
+
+/* PCNT_CNT_THRES1_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit6.
+ */
+
+#define PCNT_CNT_THRES1_U6  0x0000FFFF
+#define PCNT_CNT_THRES1_U6_M  ((PCNT_CNT_THRES1_U6_V)<<(PCNT_CNT_THRES1_U6_S))
+#define PCNT_CNT_THRES1_U6_V  0xFFFF
+#define PCNT_CNT_THRES1_U6_S  16
+
+/* PCNT_CNT_THRES0_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit6.
+ */
+
+#define PCNT_CNT_THRES0_U6  0x0000FFFF
+#define PCNT_CNT_THRES0_U6_M  ((PCNT_CNT_THRES0_U6_V)<<(PCNT_CNT_THRES0_U6_S))
+#define PCNT_CNT_THRES0_U6_V  0xFFFF
+#define PCNT_CNT_THRES0_U6_S  0
+
+#define PCNT_U6_CONF2_REG          (DR_REG_PCNT_BASE + 0x0050)
+
+/* PCNT_CNT_L_LIM_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit6.
+ */
+
+#define PCNT_CNT_L_LIM_U6  0x0000FFFF
+#define PCNT_CNT_L_LIM_U6_M  ((PCNT_CNT_L_LIM_U6_V)<<(PCNT_CNT_L_LIM_U6_S))
+#define PCNT_CNT_L_LIM_U6_V  0xFFFF
+#define PCNT_CNT_L_LIM_U6_S  16
+
+/* PCNT_CNT_H_LIM_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit6.
+ */
+
+#define PCNT_CNT_H_LIM_U6  0x0000FFFF
+#define PCNT_CNT_H_LIM_U6_M  ((PCNT_CNT_H_LIM_U6_V)<<(PCNT_CNT_H_LIM_U6_S))
+#define PCNT_CNT_H_LIM_U6_V  0xFFFF
+#define PCNT_CNT_H_LIM_U6_S  0
+
+#define PCNT_U7_CONF0_REG          (DR_REG_PCNT_BASE + 0x0054)
+
+/* PCNT_CH1_LCTRL_MODE_U7 : R/W ;bitpos:[31:30] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U7_M  ((PCNT_CH1_LCTRL_MODE_U7_V)<<(PCNT_CH1_LCTRL_MODE_U7_S))
+#define PCNT_CH1_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U7_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U7 : R/W ;bitpos:[29:28] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U7_M  ((PCNT_CH1_HCTRL_MODE_U7_V)<<(PCNT_CH1_HCTRL_MODE_U7_S))
+#define PCNT_CH1_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U7_S  28
+
+/* PCNT_CH1_POS_MODE_U7 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2:decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U7  0x00000003
+#define PCNT_CH1_POS_MODE_U7_M  ((PCNT_CH1_POS_MODE_U7_V)<<(PCNT_CH1_POS_MODE_U7_S))
+#define PCNT_CH1_POS_MODE_U7_V  0x3
+#define PCNT_CH1_POS_MODE_U7_S  26
+
+/* PCNT_CH1_NEG_MODE_U7 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U7  0x00000003
+#define PCNT_CH1_NEG_MODE_U7_M  ((PCNT_CH1_NEG_MODE_U7_V)<<(PCNT_CH1_NEG_MODE_U7_S))
+#define PCNT_CH1_NEG_MODE_U7_V  0x3
+#define PCNT_CH1_NEG_MODE_U7_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U7 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U7_M  ((PCNT_CH0_LCTRL_MODE_U7_V)<<(PCNT_CH0_LCTRL_MODE_U7_S))
+#define PCNT_CH0_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U7_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U7 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U7_M  ((PCNT_CH0_HCTRL_MODE_U7_V)<<(PCNT_CH0_HCTRL_MODE_U7_S))
+#define PCNT_CH0_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U7_S  20
+
+/* PCNT_CH0_POS_MODE_U7 : R/W ;bitpos:[19:18] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U7  0x00000003
+#define PCNT_CH0_POS_MODE_U7_M  ((PCNT_CH0_POS_MODE_U7_V)<<(PCNT_CH0_POS_MODE_U7_S))
+#define PCNT_CH0_POS_MODE_U7_V  0x3
+#define PCNT_CH0_POS_MODE_U7_S  18
+
+/* PCNT_CH0_NEG_MODE_U7 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * input negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U7  0x00000003
+#define PCNT_CH0_NEG_MODE_U7_M  ((PCNT_CH0_NEG_MODE_U7_V)<<(PCNT_CH0_NEG_MODE_U7_S))
+#define PCNT_CH0_NEG_MODE_U7_V  0x3
+#define PCNT_CH0_NEG_MODE_U7_S  16
+
+/* PCNT_THR_THRES1_EN_U7 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit7's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U7  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_V  0x1
+#define PCNT_THR_THRES1_EN_U7_S  15
+
+/* PCNT_THR_THRES0_EN_U7 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U7  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_V  0x1
+#define PCNT_THR_THRES0_EN_U7_S  14
+
+/* PCNT_THR_L_LIM_EN_U7 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U7  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_V  0x1
+#define PCNT_THR_L_LIM_EN_U7_S  13
+
+/* PCNT_THR_H_LIM_EN_U7 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit7's count
+ * with thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U7  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_V  0x1
+#define PCNT_THR_H_LIM_EN_U7_S  12
+
+/* PCNT_THR_ZERO_EN_U7 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U7  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_V  0x1
+#define PCNT_THR_ZERO_EN_U7_S  11
+
+/* PCNT_FILTER_EN_U7 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit7.
+ */
+
+#define PCNT_FILTER_EN_U7  (BIT(10))
+#define PCNT_FILTER_EN_U7_M  (BIT(10))
+#define PCNT_FILTER_EN_U7_V  0x1
+#define PCNT_FILTER_EN_U7_S  10
+
+/* PCNT_FILTER_THRES_U7 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit7.
+ */
+
+#define PCNT_FILTER_THRES_U7  0x000003FF
+#define PCNT_FILTER_THRES_U7_M  ((PCNT_FILTER_THRES_U7_V)<<(PCNT_FILTER_THRES_U7_S))
+#define PCNT_FILTER_THRES_U7_V  0x3FF
+#define PCNT_FILTER_THRES_U7_S  0
+
+#define PCNT_U7_CONF1_REG          (DR_REG_PCNT_BASE + 0x0058)
+
+/* PCNT_CNT_THRES1_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit7.
+ */
+
+#define PCNT_CNT_THRES1_U7  0x0000FFFF
+#define PCNT_CNT_THRES1_U7_M  ((PCNT_CNT_THRES1_U7_V)<<(PCNT_CNT_THRES1_U7_S))
+#define PCNT_CNT_THRES1_U7_V  0xFFFF
+#define PCNT_CNT_THRES1_U7_S  16
+
+/* PCNT_CNT_THRES0_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit7.
+ */
+
+#define PCNT_CNT_THRES0_U7  0x0000FFFF
+#define PCNT_CNT_THRES0_U7_M  ((PCNT_CNT_THRES0_U7_V)<<(PCNT_CNT_THRES0_U7_S))
+#define PCNT_CNT_THRES0_U7_V  0xFFFF
+#define PCNT_CNT_THRES0_U7_S  0
+
+#define PCNT_U7_CONF2_REG          (DR_REG_PCNT_BASE + 0x005c)
+
+/* PCNT_CNT_L_LIM_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit7.
+ */
+
+#define PCNT_CNT_L_LIM_U7  0x0000FFFF
+#define PCNT_CNT_L_LIM_U7_M  ((PCNT_CNT_L_LIM_U7_V)<<(PCNT_CNT_L_LIM_U7_S))
+#define PCNT_CNT_L_LIM_U7_V  0xFFFF
+#define PCNT_CNT_L_LIM_U7_S  16
+
+/* PCNT_CNT_H_LIM_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit7.
+ */
+
+#define PCNT_CNT_H_LIM_U7  0x0000FFFF
+#define PCNT_CNT_H_LIM_U7_M  ((PCNT_CNT_H_LIM_U7_V)<<(PCNT_CNT_H_LIM_U7_S))
+#define PCNT_CNT_H_LIM_U7_V  0xFFFF
+#define PCNT_CNT_H_LIM_U7_S  0
+
+#define PCNT_U0_CNT_REG          (DR_REG_PCNT_BASE + 0x0060)
+
+/* PCNT_PLUS_CNT_U0 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit0.
+ */
+
+#define PCNT_PLUS_CNT_U0  0x0000FFFF
+#define PCNT_PLUS_CNT_U0_M  ((PCNT_PLUS_CNT_U0_V)<<(PCNT_PLUS_CNT_U0_S))
+#define PCNT_PLUS_CNT_U0_V  0xFFFF
+#define PCNT_PLUS_CNT_U0_S  0
+
+#define PCNT_U1_CNT_REG          (DR_REG_PCNT_BASE + 0x0064)
+
+/* PCNT_PLUS_CNT_U1 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit1.
+ */
+
+#define PCNT_PLUS_CNT_U1  0x0000FFFF
+#define PCNT_PLUS_CNT_U1_M  ((PCNT_PLUS_CNT_U1_V)<<(PCNT_PLUS_CNT_U1_S))
+#define PCNT_PLUS_CNT_U1_V  0xFFFF
+#define PCNT_PLUS_CNT_U1_S  0
+
+#define PCNT_U2_CNT_REG          (DR_REG_PCNT_BASE + 0x0068)
+
+/* PCNT_PLUS_CNT_U2 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit2.
+ */
+
+#define PCNT_PLUS_CNT_U2  0x0000FFFF
+#define PCNT_PLUS_CNT_U2_M  ((PCNT_PLUS_CNT_U2_V)<<(PCNT_PLUS_CNT_U2_S))
+#define PCNT_PLUS_CNT_U2_V  0xFFFF
+#define PCNT_PLUS_CNT_U2_S  0
+
+#define PCNT_U3_CNT_REG          (DR_REG_PCNT_BASE + 0x006c)
+
+/* PCNT_PLUS_CNT_U3 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit3.
+ */
+
+#define PCNT_PLUS_CNT_U3  0x0000FFFF
+#define PCNT_PLUS_CNT_U3_M  ((PCNT_PLUS_CNT_U3_V)<<(PCNT_PLUS_CNT_U3_S))
+#define PCNT_PLUS_CNT_U3_V  0xFFFF
+#define PCNT_PLUS_CNT_U3_S  0
+
+#define PCNT_U4_CNT_REG          (DR_REG_PCNT_BASE + 0x0070)
+
+/* PCNT_PLUS_CNT_U4 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit4.
+ */
+
+#define PCNT_PLUS_CNT_U4  0x0000FFFF
+#define PCNT_PLUS_CNT_U4_M  ((PCNT_PLUS_CNT_U4_V)<<(PCNT_PLUS_CNT_U4_S))
+#define PCNT_PLUS_CNT_U4_V  0xFFFF
+#define PCNT_PLUS_CNT_U4_S  0
+
+#define PCNT_U5_CNT_REG          (DR_REG_PCNT_BASE + 0x0074)
+
+/* PCNT_PLUS_CNT_U5 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit5.
+ */
+
+#define PCNT_PLUS_CNT_U5  0x0000FFFF
+#define PCNT_PLUS_CNT_U5_M  ((PCNT_PLUS_CNT_U5_V)<<(PCNT_PLUS_CNT_U5_S))
+#define PCNT_PLUS_CNT_U5_V  0xFFFF
+#define PCNT_PLUS_CNT_U5_S  0
+
+#define PCNT_U6_CNT_REG          (DR_REG_PCNT_BASE + 0x0078)
+
+/* PCNT_PLUS_CNT_U6 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit6.
+ */
+
+#define PCNT_PLUS_CNT_U6  0x0000FFFF
+#define PCNT_PLUS_CNT_U6_M  ((PCNT_PLUS_CNT_U6_V)<<(PCNT_PLUS_CNT_U6_S))
+#define PCNT_PLUS_CNT_U6_V  0xFFFF
+#define PCNT_PLUS_CNT_U6_S  0
+
+#define PCNT_U7_CNT_REG          (DR_REG_PCNT_BASE + 0x007c)
+
+/* PCNT_PLUS_CNT_U7 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit7.
+ */
+
+#define PCNT_PLUS_CNT_U7  0x0000FFFF
+#define PCNT_PLUS_CNT_U7_M  ((PCNT_PLUS_CNT_U7_V)<<(PCNT_PLUS_CNT_U7_S))
+#define PCNT_PLUS_CNT_U7_V  0xFFFF
+#define PCNT_PLUS_CNT_U7_S  0
+
+#define PCNT_INT_RAW_REG          (DR_REG_PCNT_BASE + 0x0080)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_RAW : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_RAW : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_RAW : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_RAW : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_RAW : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_RAW : RO ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_RAW : RO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_RAW : RO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_S  0
+
+#define PCNT_INT_ST_REG          (DR_REG_PCNT_BASE + 0x0084)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ST : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ST  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ST : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ST  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ST : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ST  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ST  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ST : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ST  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ST : RO; bitpos: [2]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U2_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ST    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_M  (PCNT_CNT_THR_EVENT_U2_INT_ST_V << PCNT_CNT_THR_EVENT_U2_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ST : RO; bitpos: [1]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U1_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ST    (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_M  (PCNT_CNT_THR_EVENT_U1_INT_ST_V << PCNT_CNT_THR_EVENT_U1_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ST : RO; bitpos: [0]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U0_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ST    (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_M  (PCNT_CNT_THR_EVENT_U0_INT_ST_V << PCNT_CNT_THR_EVENT_U0_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_S  0
+
+/* PCNT_INT_ENA_REG register
+ * Interrupt enable register
+ */
+
+#define PCNT_INT_ENA_REG          (DR_REG_PCNT_BASE + 0x0088)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ENA : R/W ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ENA : R/W ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ENA : R/W ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ENA : R/W ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ENA : R/W ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ENA : R/W ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_S  0
+
+#define PCNT_INT_CLR_REG          (DR_REG_PCNT_BASE + 0x008c)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_CLR : WO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel7 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_CLR : WO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel6 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_CLR : WO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel5 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_CLR : WO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel4 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_CLR : WO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel3 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_CLR : WO; bitpos: [2]; default: 0;
+ * Set this bit to clear the PCNT_CNT_THR_EVENT_U2_INT interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_M  (PCNT_CNT_THR_EVENT_U2_INT_CLR_V << PCNT_CNT_THR_EVENT_U2_INT_CLR_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_CLR : WO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel1 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_CLR : WO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel0 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_S  0
+
+#define PCNT_U0_STATUS_REG          (DR_REG_PCNT_BASE + 0x0090)
+
+/* PCNT_CORE_STATUS_U0 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U0  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_M  ((PCNT_CORE_STATUS_U0_V)<<(PCNT_CORE_STATUS_U0_S))
+#define PCNT_CORE_STATUS_U0_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_S  0
+
+/* 0: positive value to zero;
+ * 1: negative value to zero;
+ * 2: counter value negative;
+ * 3: counter value positive
+ */
+
+#define PCNT_STATUS_CNT_MODE    0x3
+#define PCNT_STATUS_CNT_MODE_M  ((PCNT_STATUS_CNT_MODE_V)<<(PCNT_STATUS_CNT_MODE_S))
+#define PCNT_STATUS_CNT_MODE_V  0x3
+#define PCNT_STATUS_CNT_MODE_S  0
+
+/* counter value equals to thresh1 */
+
+#define PCNT_STATUS_THRES1    BIT(2)
+#define PCNT_STATUS_THRES1_M  BIT(2)
+#define PCNT_STATUS_THRES1_V  0x1
+#define PCNT_STATUS_THRES1_S  2
+
+/* counter value equals to thresh0 */
+
+#define PCNT_STATUS_THRES0    BIT(3)
+#define PCNT_STATUS_THRES0_M  BIT(3)
+#define PCNT_STATUS_THRES0_V  0x1
+#define PCNT_STATUS_THRES0_S  3
+
+/* counter value reaches h_lim */
+
+#define PCNT_STATUS_L_LIM    BIT(4)
+#define PCNT_STATUS_L_LIM_M  BIT(4)
+#define PCNT_STATUS_L_LIM_V  0x1
+#define PCNT_STATUS_L_LIM_S  4
+
+/* counter value reaches l_lim */
+
+#define PCNT_STATUS_H_LIM    BIT(5)
+#define PCNT_STATUS_H_LIM_M  BIT(5)
+#define PCNT_STATUS_H_LIM_V  0x1
+#define PCNT_STATUS_H_LIM_S  5
+
+/* counter value equals to zero */
+
+#define PCNT_STATUS_ZERO    BIT(6)
+#define PCNT_STATUS_ZERO_M  BIT(6)
+#define PCNT_STATUS_ZERO_V  0x1
+#define PCNT_STATUS_ZERO_S  6
+
+#define PCNT_U1_STATUS_REG          (DR_REG_PCNT_BASE + 0x0094)
+
+/* PCNT_CORE_STATUS_U1 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U1  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_M  ((PCNT_CORE_STATUS_U1_V)<<(PCNT_CORE_STATUS_U1_S))
+#define PCNT_CORE_STATUS_U1_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_S  0
+
+#define PCNT_U2_STATUS_REG          (DR_REG_PCNT_BASE + 0x0098)
+
+/* PCNT_CORE_STATUS_U2 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U2  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_M  ((PCNT_CORE_STATUS_U2_V)<<(PCNT_CORE_STATUS_U2_S))
+#define PCNT_CORE_STATUS_U2_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_S  0
+
+#define PCNT_U3_STATUS_REG          (DR_REG_PCNT_BASE + 0x009c)
+
+/* PCNT_CORE_STATUS_U3 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U3  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_M  ((PCNT_CORE_STATUS_U3_V)<<(PCNT_CORE_STATUS_U3_S))
+#define PCNT_CORE_STATUS_U3_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_S  0
+
+#define PCNT_U4_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a0)
+/* PCNT_CORE_STATUS_U4 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U4  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_M  ((PCNT_CORE_STATUS_U4_V)<<(PCNT_CORE_STATUS_U4_S))
+#define PCNT_CORE_STATUS_U4_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_S  0
+
+#define PCNT_U5_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a4)
+/* PCNT_CORE_STATUS_U5 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U5  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_M  ((PCNT_CORE_STATUS_U5_V)<<(PCNT_CORE_STATUS_U5_S))
+#define PCNT_CORE_STATUS_U5_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_S  0
+
+#define PCNT_U6_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a8)
+/* PCNT_CORE_STATUS_U6 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U6  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_M  ((PCNT_CORE_STATUS_U6_V)<<(PCNT_CORE_STATUS_U6_S))
+#define PCNT_CORE_STATUS_U6_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_S  0
+
+#define PCNT_U7_STATUS_REG          (DR_REG_PCNT_BASE + 0x00ac)
+
+/* PCNT_CORE_STATUS_U7 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U7  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_M  ((PCNT_CORE_STATUS_U7_V)<<(PCNT_CORE_STATUS_U7_S))
+#define PCNT_CORE_STATUS_U7_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_S  0
+
+#define PCNT_CTRL_REG          (DR_REG_PCNT_BASE + 0x00b0)
+
+/* PCNT_CLK_EN : R/W ;bitpos:[16] ;default: 1'b0 ; */
+
+#define PCNT_CLK_EN  (BIT(16))
+#define PCNT_CLK_EN_M  (BIT(16))
+#define PCNT_CLK_EN_V  0x1
+#define PCNT_CLK_EN_S  16
+
+/* PCNT_CNT_PAUSE_U7 : R/W ;bitpos:[15] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit7's counter. */
+
+#define PCNT_CNT_PAUSE_U7  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_M  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_V  0x1
+#define PCNT_CNT_PAUSE_U7_S  15
+
+/* PCNT_PLUS_CNT_RST_U7 : R/W ;bitpos:[14] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit7's counter. */
+
+#define PCNT_PLUS_CNT_RST_U7  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_M  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_V  0x1
+#define PCNT_PLUS_CNT_RST_U7_S  14
+
+/* PCNT_CNT_PAUSE_U6 : R/W ;bitpos:[13] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit6's counter. */
+
+#define PCNT_CNT_PAUSE_U6  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_M  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_V  0x1
+#define PCNT_CNT_PAUSE_U6_S  13
+
+/* PCNT_PLUS_CNT_RST_U6 : R/W ;bitpos:[12] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit6's counter. */
+
+#define PCNT_PLUS_CNT_RST_U6  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_M  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_V  0x1
+#define PCNT_PLUS_CNT_RST_U6_S  12
+
+/* PCNT_CNT_PAUSE_U5 : R/W ;bitpos:[11] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit5's counter. */
+
+#define PCNT_CNT_PAUSE_U5  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_M  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_V  0x1
+#define PCNT_CNT_PAUSE_U5_S  11
+
+/* PCNT_PLUS_CNT_RST_U5 : R/W ;bitpos:[10] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit5's counter. */
+
+#define PCNT_PLUS_CNT_RST_U5  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_M  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_V  0x1
+#define PCNT_PLUS_CNT_RST_U5_S  10
+
+/* PCNT_CNT_PAUSE_U4 : R/W ;bitpos:[9] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit4's counter. */
+
+#define PCNT_CNT_PAUSE_U4  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_M  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_V  0x1
+#define PCNT_CNT_PAUSE_U4_S  9
+
+/* PCNT_PLUS_CNT_RST_U4 : R/W ;bitpos:[8] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit4's counter. */
+
+#define PCNT_PLUS_CNT_RST_U4  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_M  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_V  0x1
+#define PCNT_PLUS_CNT_RST_U4_S  8
+
+/* PCNT_CNT_PAUSE_U3 : R/W ;bitpos:[7] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit3's counter. */
+
+#define PCNT_CNT_PAUSE_U3  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_M  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_V  0x1
+#define PCNT_CNT_PAUSE_U3_S  7
+
+/* PCNT_PLUS_CNT_RST_U3 : R/W ;bitpos:[6] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit3's counter. */
+
+#define PCNT_PLUS_CNT_RST_U3  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_M  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_V  0x1
+#define PCNT_PLUS_CNT_RST_U3_S  6
+
+/* PCNT_CNT_PAUSE_U2 : R/W ;bitpos:[5] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit2's counter. */
+
+#define PCNT_CNT_PAUSE_U2  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_M  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_V  0x1
+#define PCNT_CNT_PAUSE_U2_S  5
+
+/* PCNT_PLUS_CNT_RST_U2 : R/W ;bitpos:[4] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit2's counter. */
+
+#define PCNT_PLUS_CNT_RST_U2  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_M  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_V  0x1
+#define PCNT_PLUS_CNT_RST_U2_S  4
+
+/* PCNT_CNT_PAUSE_U1 : R/W ;bitpos:[3] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit1's counter. */
+
+#define PCNT_CNT_PAUSE_U1  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_M  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_V  0x1
+#define PCNT_CNT_PAUSE_U1_S  3
+
+/* PCNT_PLUS_CNT_RST_U1 : R/W ;bitpos:[2] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit1's counter. */
+
+#define PCNT_PLUS_CNT_RST_U1  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_M  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_V  0x1
+#define PCNT_PLUS_CNT_RST_U1_S  2
+
+/* PCNT_CNT_PAUSE_U0 : R/W ;bitpos:[1] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit0's counter. */
+
+#define PCNT_CNT_PAUSE_U0  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_M  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_V  0x1
+#define PCNT_CNT_PAUSE_U0_S  1
+
+/* PCNT_PLUS_CNT_RST_U0 : R/W ;bitpos:[0] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit0's counter. */
+
+#define PCNT_PLUS_CNT_RST_U0  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_M  (BIT(0))

Review Comment:
   ```suggestion
   #define PCNT_PLUS_CNT_RST_U0  BIT(0)
   #define PCNT_PLUS_CNT_RST_U0_M  BIT(0)
   ```
   optional. here and other similar places. of course if this is not auto-generated



##########
arch/xtensa/src/esp32/hardware/esp32_pcnt.h:
##########
@@ -0,0 +1,2495 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/hardware/esp32_pcnt.h
+ *
+ * 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_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+#define __ARCH_XTENSA_SRC_ESP32_HARDWARE_ESP32_PCNT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* PCNT_U0_CONF0_REG register
+ * Configuration register 0 for unit 0
+ */
+
+#define PCNT_U0_CONF0_REG (DR_REG_PCNT_BASE + 0x0)
+
+/* PCNT_CH1_LCTRL_MODE_U0 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_M  (PCNT_CH1_LCTRL_MODE_U0_V << PCNT_CH1_LCTRL_MODE_U0_S)
+#define PCNT_CH1_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U0_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U0 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_M  (PCNT_CH1_HCTRL_MODE_U0_V << PCNT_CH1_HCTRL_MODE_U0_S)
+#define PCNT_CH1_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U0_S  28
+
+/* PCNT_CH1_POS_MODE_U0 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U0    0x00000003
+#define PCNT_CH1_POS_MODE_U0_M  (PCNT_CH1_POS_MODE_U0_V << PCNT_CH1_POS_MODE_U0_S)
+#define PCNT_CH1_POS_MODE_U0_V  0x00000003
+#define PCNT_CH1_POS_MODE_U0_S  26
+
+/* PCNT_CH1_NEG_MODE_U0 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U0    0x00000003
+#define PCNT_CH1_NEG_MODE_U0_M  (PCNT_CH1_NEG_MODE_U0_V << PCNT_CH1_NEG_MODE_U0_S)
+#define PCNT_CH1_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U0_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U0 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_M  (PCNT_CH0_LCTRL_MODE_U0_V << PCNT_CH0_LCTRL_MODE_U0_S)
+#define PCNT_CH0_LCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U0_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U0 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH0_POS_MODE/CH0_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U0    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_M  (PCNT_CH0_HCTRL_MODE_U0_V << PCNT_CH0_HCTRL_MODE_U0_S)
+#define PCNT_CH0_HCTRL_MODE_U0_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U0_S  20
+
+/* PCNT_CH0_POS_MODE_U0 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U0    0x00000003
+#define PCNT_CH0_POS_MODE_U0_M  (PCNT_CH0_POS_MODE_U0_V << PCNT_CH0_POS_MODE_U0_S)
+#define PCNT_CH0_POS_MODE_U0_V  0x00000003
+#define PCNT_CH0_POS_MODE_U0_S  18
+
+/* PCNT_CH0_NEG_MODE_U0 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U0    0x00000003
+#define PCNT_CH0_NEG_MODE_U0_M  (PCNT_CH0_NEG_MODE_U0_V << PCNT_CH0_NEG_MODE_U0_S)
+#define PCNT_CH0_NEG_MODE_U0_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U0_S  16
+
+/* PCNT_THR_THRES1_EN_U0 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 0's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U0    (BIT(15))
+#define PCNT_THR_THRES1_EN_U0_M  (PCNT_THR_THRES1_EN_U0_V << PCNT_THR_THRES1_EN_U0_S)
+#define PCNT_THR_THRES1_EN_U0_V  0x00000001
+#define PCNT_THR_THRES1_EN_U0_S  15
+
+/* PCNT_THR_THRES0_EN_U0 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 0's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U0    (BIT(14))
+#define PCNT_THR_THRES0_EN_U0_M  (PCNT_THR_THRES0_EN_U0_V << PCNT_THR_THRES0_EN_U0_S)
+#define PCNT_THR_THRES0_EN_U0_V  0x00000001
+#define PCNT_THR_THRES0_EN_U0_S  14
+
+/* PCNT_THR_L_LIM_EN_U0 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 0's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U0    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U0_M  (PCNT_THR_L_LIM_EN_U0_V << PCNT_THR_L_LIM_EN_U0_S)
+#define PCNT_THR_L_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U0_S  13
+
+/* PCNT_THR_H_LIM_EN_U0 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 0's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U0    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U0_M  (PCNT_THR_H_LIM_EN_U0_V << PCNT_THR_H_LIM_EN_U0_S)
+#define PCNT_THR_H_LIM_EN_U0_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U0_S  12
+
+/* PCNT_THR_ZERO_EN_U0 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 0's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U0    (BIT(11))
+#define PCNT_THR_ZERO_EN_U0_M  (PCNT_THR_ZERO_EN_U0_V << PCNT_THR_ZERO_EN_U0_S)
+#define PCNT_THR_ZERO_EN_U0_V  0x00000001
+#define PCNT_THR_ZERO_EN_U0_S  11
+
+/* PCNT_FILTER_EN_U0 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 0's input filter.
+ */
+
+#define PCNT_FILTER_EN_U0    (BIT(10))
+#define PCNT_FILTER_EN_U0_M  (PCNT_FILTER_EN_U0_V << PCNT_FILTER_EN_U0_S)
+#define PCNT_FILTER_EN_U0_V  0x00000001
+#define PCNT_FILTER_EN_U0_S  10
+
+/* PCNT_FILTER_THRES_U0 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U0    0x000003ff
+#define PCNT_FILTER_THRES_U0_M  (PCNT_FILTER_THRES_U0_V << PCNT_FILTER_THRES_U0_S)
+#define PCNT_FILTER_THRES_U0_V  0x000003ff
+#define PCNT_FILTER_THRES_U0_S  0
+
+/* PCNT_U0_CONF1_REG register
+ * Configuration register 1 for unit 0
+ */
+
+#define PCNT_U0_CONF1_REG (DR_REG_PCNT_BASE + 0x4)
+
+/* PCNT_CNT_THRES1_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES1_U0    0x0000ffff
+#define PCNT_CNT_THRES1_U0_M  (PCNT_CNT_THRES1_U0_V << PCNT_CNT_THRES1_U0_S)
+#define PCNT_CNT_THRES1_U0_V  0x0000ffff
+#define PCNT_CNT_THRES1_U0_S  16
+
+/* PCNT_CNT_THRES0_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 0.
+ */
+
+#define PCNT_CNT_THRES0_U0    0x0000ffff
+#define PCNT_CNT_THRES0_U0_M  (PCNT_CNT_THRES0_U0_V << PCNT_CNT_THRES0_U0_S)
+#define PCNT_CNT_THRES0_U0_V  0x0000ffff
+#define PCNT_CNT_THRES0_U0_S  0
+
+/* PCNT_U0_CONF2_REG register
+ * Configuration register 2 for unit 0
+ */
+
+#define PCNT_U0_CONF2_REG (DR_REG_PCNT_BASE + 0x8)
+
+/* PCNT_CNT_L_LIM_U0 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 0.
+ */
+
+#define PCNT_CNT_L_LIM_U0    0x0000ffff
+#define PCNT_CNT_L_LIM_U0_M  (PCNT_CNT_L_LIM_U0_V << PCNT_CNT_L_LIM_U0_S)
+#define PCNT_CNT_L_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U0_S  16
+
+/* PCNT_CNT_H_LIM_U0 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 0.
+ */
+
+#define PCNT_CNT_H_LIM_U0    0x0000ffff
+#define PCNT_CNT_H_LIM_U0_M  (PCNT_CNT_H_LIM_U0_V << PCNT_CNT_H_LIM_U0_S)
+#define PCNT_CNT_H_LIM_U0_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U0_S  0
+
+/* PCNT_U1_CONF0_REG register
+ * Configuration register 0 for unit 1
+ */
+
+#define PCNT_U1_CONF0_REG (DR_REG_PCNT_BASE + 0xc)
+
+/* PCNT_CH1_LCTRL_MODE_U1 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_M  (PCNT_CH1_LCTRL_MODE_U1_V << PCNT_CH1_LCTRL_MODE_U1_S)
+#define PCNT_CH1_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U1_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U1 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_M  (PCNT_CH1_HCTRL_MODE_U1_V << PCNT_CH1_HCTRL_MODE_U1_S)
+#define PCNT_CH1_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U1_S  28
+
+/* PCNT_CH1_POS_MODE_U1 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U1    0x00000003
+#define PCNT_CH1_POS_MODE_U1_M  (PCNT_CH1_POS_MODE_U1_V << PCNT_CH1_POS_MODE_U1_S)
+#define PCNT_CH1_POS_MODE_U1_V  0x00000003
+#define PCNT_CH1_POS_MODE_U1_S  26
+
+/* PCNT_CH1_NEG_MODE_U1 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U1    0x00000003
+#define PCNT_CH1_NEG_MODE_U1_M  (PCNT_CH1_NEG_MODE_U1_V << PCNT_CH1_NEG_MODE_U1_S)
+#define PCNT_CH1_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U1_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U1 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_M  (PCNT_CH0_LCTRL_MODE_U1_V << PCNT_CH0_LCTRL_MODE_U1_S)
+#define PCNT_CH0_LCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U1_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U1 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH1_POS_MODE/CH1_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U1    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_M  (PCNT_CH0_HCTRL_MODE_U1_V << PCNT_CH0_HCTRL_MODE_U1_S)
+#define PCNT_CH0_HCTRL_MODE_U1_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U1_S  20
+
+/* PCNT_CH0_POS_MODE_U1 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U1    0x00000003
+#define PCNT_CH0_POS_MODE_U1_M  (PCNT_CH0_POS_MODE_U1_V << PCNT_CH0_POS_MODE_U1_S)
+#define PCNT_CH0_POS_MODE_U1_V  0x00000003
+#define PCNT_CH0_POS_MODE_U1_S  18
+
+/* PCNT_CH0_NEG_MODE_U1 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U1    0x00000003
+#define PCNT_CH0_NEG_MODE_U1_M  (PCNT_CH0_NEG_MODE_U1_V << PCNT_CH0_NEG_MODE_U1_S)
+#define PCNT_CH0_NEG_MODE_U1_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U1_S  16
+
+/* PCNT_THR_THRES1_EN_U1 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 1's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U1    (BIT(15))
+#define PCNT_THR_THRES1_EN_U1_M  (PCNT_THR_THRES1_EN_U1_V << PCNT_THR_THRES1_EN_U1_S)
+#define PCNT_THR_THRES1_EN_U1_V  0x00000001
+#define PCNT_THR_THRES1_EN_U1_S  15
+
+/* PCNT_THR_THRES0_EN_U1 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 1's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U1    (BIT(14))
+#define PCNT_THR_THRES0_EN_U1_M  (PCNT_THR_THRES0_EN_U1_V << PCNT_THR_THRES0_EN_U1_S)
+#define PCNT_THR_THRES0_EN_U1_V  0x00000001
+#define PCNT_THR_THRES0_EN_U1_S  14
+
+/* PCNT_THR_L_LIM_EN_U1 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 1's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U1    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U1_M  (PCNT_THR_L_LIM_EN_U1_V << PCNT_THR_L_LIM_EN_U1_S)
+#define PCNT_THR_L_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U1_S  13
+
+/* PCNT_THR_H_LIM_EN_U1 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 1's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U1    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U1_M  (PCNT_THR_H_LIM_EN_U1_V << PCNT_THR_H_LIM_EN_U1_S)
+#define PCNT_THR_H_LIM_EN_U1_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U1_S  12
+
+/* PCNT_THR_ZERO_EN_U1 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 1's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U1    (BIT(11))
+#define PCNT_THR_ZERO_EN_U1_M  (PCNT_THR_ZERO_EN_U1_V << PCNT_THR_ZERO_EN_U1_S)
+#define PCNT_THR_ZERO_EN_U1_V  0x00000001
+#define PCNT_THR_ZERO_EN_U1_S  11
+
+/* PCNT_FILTER_EN_U1 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 1's input filter.
+ */
+
+#define PCNT_FILTER_EN_U1    (BIT(10))
+#define PCNT_FILTER_EN_U1_M  (PCNT_FILTER_EN_U1_V << PCNT_FILTER_EN_U1_S)
+#define PCNT_FILTER_EN_U1_V  0x00000001
+#define PCNT_FILTER_EN_U1_S  10
+
+/* PCNT_FILTER_THRES_U1 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U1    0x000003ff
+#define PCNT_FILTER_THRES_U1_M  (PCNT_FILTER_THRES_U1_V << PCNT_FILTER_THRES_U1_S)
+#define PCNT_FILTER_THRES_U1_V  0x000003ff
+#define PCNT_FILTER_THRES_U1_S  0
+
+/* PCNT_U1_CONF1_REG register
+ * Configuration register 1 for unit 1
+ */
+
+#define PCNT_U1_CONF1_REG (DR_REG_PCNT_BASE + 0x10)
+
+/* PCNT_CNT_THRES1_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES1_U1    0x0000ffff
+#define PCNT_CNT_THRES1_U1_M  (PCNT_CNT_THRES1_U1_V << PCNT_CNT_THRES1_U1_S)
+#define PCNT_CNT_THRES1_U1_V  0x0000ffff
+#define PCNT_CNT_THRES1_U1_S  16
+
+/* PCNT_CNT_THRES0_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 1.
+ */
+
+#define PCNT_CNT_THRES0_U1    0x0000ffff
+#define PCNT_CNT_THRES0_U1_M  (PCNT_CNT_THRES0_U1_V << PCNT_CNT_THRES0_U1_S)
+#define PCNT_CNT_THRES0_U1_V  0x0000ffff
+#define PCNT_CNT_THRES0_U1_S  0
+
+/* PCNT_U1_CONF2_REG register
+ * Configuration register 2 for unit 1
+ */
+
+#define PCNT_U1_CONF2_REG (DR_REG_PCNT_BASE + 0x14)
+
+/* PCNT_CNT_L_LIM_U1 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 1.
+ */
+
+#define PCNT_CNT_L_LIM_U1    0x0000ffff
+#define PCNT_CNT_L_LIM_U1_M  (PCNT_CNT_L_LIM_U1_V << PCNT_CNT_L_LIM_U1_S)
+#define PCNT_CNT_L_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U1_S  16
+
+/* PCNT_CNT_H_LIM_U1 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 1.
+ */
+
+#define PCNT_CNT_H_LIM_U1    0x0000ffff
+#define PCNT_CNT_H_LIM_U1_M  (PCNT_CNT_H_LIM_U1_V << PCNT_CNT_H_LIM_U1_S)
+#define PCNT_CNT_H_LIM_U1_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U1_S  0
+
+/* PCNT_U2_CONF0_REG register
+ * Configuration register 0 for unit 2
+ */
+
+#define PCNT_U2_CONF0_REG (DR_REG_PCNT_BASE + 0x18)
+
+/* PCNT_CH1_LCTRL_MODE_U2 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_M  (PCNT_CH1_LCTRL_MODE_U2_V << PCNT_CH1_LCTRL_MODE_U2_S)
+#define PCNT_CH1_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U2_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U2 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_M  (PCNT_CH1_HCTRL_MODE_U2_V << PCNT_CH1_HCTRL_MODE_U2_S)
+#define PCNT_CH1_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U2_S  28
+
+/* PCNT_CH1_POS_MODE_U2 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U2    0x00000003
+#define PCNT_CH1_POS_MODE_U2_M  (PCNT_CH1_POS_MODE_U2_V << PCNT_CH1_POS_MODE_U2_S)
+#define PCNT_CH1_POS_MODE_U2_V  0x00000003
+#define PCNT_CH1_POS_MODE_U2_S  26
+
+/* PCNT_CH1_NEG_MODE_U2 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U2    0x00000003
+#define PCNT_CH1_NEG_MODE_U2_M  (PCNT_CH1_NEG_MODE_U2_V << PCNT_CH1_NEG_MODE_U2_S)
+#define PCNT_CH1_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U2_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U2 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_M  (PCNT_CH0_LCTRL_MODE_U2_V << PCNT_CH0_LCTRL_MODE_U2_S)
+#define PCNT_CH0_LCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U2_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U2 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH2_POS_MODE/CH2_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U2    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_M  (PCNT_CH0_HCTRL_MODE_U2_V << PCNT_CH0_HCTRL_MODE_U2_S)
+#define PCNT_CH0_HCTRL_MODE_U2_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U2_S  20
+
+/* PCNT_CH0_POS_MODE_U2 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U2    0x00000003
+#define PCNT_CH0_POS_MODE_U2_M  (PCNT_CH0_POS_MODE_U2_V << PCNT_CH0_POS_MODE_U2_S)
+#define PCNT_CH0_POS_MODE_U2_V  0x00000003
+#define PCNT_CH0_POS_MODE_U2_S  18
+
+/* PCNT_CH0_NEG_MODE_U2 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U2    0x00000003
+#define PCNT_CH0_NEG_MODE_U2_M  (PCNT_CH0_NEG_MODE_U2_V << PCNT_CH0_NEG_MODE_U2_S)
+#define PCNT_CH0_NEG_MODE_U2_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U2_S  16
+
+/* PCNT_THR_THRES1_EN_U2 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 2's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U2    (BIT(15))
+#define PCNT_THR_THRES1_EN_U2_M  (PCNT_THR_THRES1_EN_U2_V << PCNT_THR_THRES1_EN_U2_S)
+#define PCNT_THR_THRES1_EN_U2_V  0x00000001
+#define PCNT_THR_THRES1_EN_U2_S  15
+
+/* PCNT_THR_THRES0_EN_U2 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 2's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U2    (BIT(14))
+#define PCNT_THR_THRES0_EN_U2_M  (PCNT_THR_THRES0_EN_U2_V << PCNT_THR_THRES0_EN_U2_S)
+#define PCNT_THR_THRES0_EN_U2_V  0x00000001
+#define PCNT_THR_THRES0_EN_U2_S  14
+
+/* PCNT_THR_L_LIM_EN_U2 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 2's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U2    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U2_M  (PCNT_THR_L_LIM_EN_U2_V << PCNT_THR_L_LIM_EN_U2_S)
+#define PCNT_THR_L_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U2_S  13
+
+/* PCNT_THR_H_LIM_EN_U2 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 2's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U2    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U2_M  (PCNT_THR_H_LIM_EN_U2_V << PCNT_THR_H_LIM_EN_U2_S)
+#define PCNT_THR_H_LIM_EN_U2_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U2_S  12
+
+/* PCNT_THR_ZERO_EN_U2 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 2's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U2    (BIT(11))
+#define PCNT_THR_ZERO_EN_U2_M  (PCNT_THR_ZERO_EN_U2_V << PCNT_THR_ZERO_EN_U2_S)
+#define PCNT_THR_ZERO_EN_U2_V  0x00000001
+#define PCNT_THR_ZERO_EN_U2_S  11
+
+/* PCNT_FILTER_EN_U2 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 2's input filter.
+ */
+
+#define PCNT_FILTER_EN_U2    (BIT(10))
+#define PCNT_FILTER_EN_U2_M  (PCNT_FILTER_EN_U2_V << PCNT_FILTER_EN_U2_S)
+#define PCNT_FILTER_EN_U2_V  0x00000001
+#define PCNT_FILTER_EN_U2_S  10
+
+/* PCNT_FILTER_THRES_U2 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U2    0x000003ff
+#define PCNT_FILTER_THRES_U2_M  (PCNT_FILTER_THRES_U2_V << PCNT_FILTER_THRES_U2_S)
+#define PCNT_FILTER_THRES_U2_V  0x000003ff
+#define PCNT_FILTER_THRES_U2_S  0
+
+/* PCNT_U2_CONF1_REG register
+ * Configuration register 1 for unit 2
+ */
+
+#define PCNT_U2_CONF1_REG (DR_REG_PCNT_BASE + 0x1c)
+
+/* PCNT_CNT_THRES1_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES1_U2    0x0000ffff
+#define PCNT_CNT_THRES1_U2_M  (PCNT_CNT_THRES1_U2_V << PCNT_CNT_THRES1_U2_S)
+#define PCNT_CNT_THRES1_U2_V  0x0000ffff
+#define PCNT_CNT_THRES1_U2_S  16
+
+/* PCNT_CNT_THRES0_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 2.
+ */
+
+#define PCNT_CNT_THRES0_U2    0x0000ffff
+#define PCNT_CNT_THRES0_U2_M  (PCNT_CNT_THRES0_U2_V << PCNT_CNT_THRES0_U2_S)
+#define PCNT_CNT_THRES0_U2_V  0x0000ffff
+#define PCNT_CNT_THRES0_U2_S  0
+
+/* PCNT_U2_CONF2_REG register
+ * Configuration register 2 for unit 2
+ */
+
+#define PCNT_U2_CONF2_REG (DR_REG_PCNT_BASE + 0x20)
+
+/* PCNT_CNT_L_LIM_U2 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 2.
+ */
+
+#define PCNT_CNT_L_LIM_U2    0x0000ffff
+#define PCNT_CNT_L_LIM_U2_M  (PCNT_CNT_L_LIM_U2_V << PCNT_CNT_L_LIM_U2_S)
+#define PCNT_CNT_L_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U2_S  16
+
+/* PCNT_CNT_H_LIM_U2 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 2.
+ */
+
+#define PCNT_CNT_H_LIM_U2    0x0000ffff
+#define PCNT_CNT_H_LIM_U2_M  (PCNT_CNT_H_LIM_U2_V << PCNT_CNT_H_LIM_U2_S)
+#define PCNT_CNT_H_LIM_U2_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U2_S  0
+
+/* PCNT_U3_CONF0_REG register
+ * Configuration register 0 for unit 3
+ */
+
+#define PCNT_U3_CONF0_REG (DR_REG_PCNT_BASE + 0x24)
+
+/* PCNT_CH1_LCTRL_MODE_U3 : R/W; bitpos: [31:30]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_M  (PCNT_CH1_LCTRL_MODE_U3_V << PCNT_CH1_LCTRL_MODE_U3_S)
+#define PCNT_CH1_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U3_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U3 : R/W; bitpos: [29:28]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_M  (PCNT_CH1_HCTRL_MODE_U3_V << PCNT_CH1_HCTRL_MODE_U3_S)
+#define PCNT_CH1_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U3_S  28
+
+/* PCNT_CH1_POS_MODE_U3 : R/W; bitpos: [27:26]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a positive edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_POS_MODE_U3    0x00000003
+#define PCNT_CH1_POS_MODE_U3_M  (PCNT_CH1_POS_MODE_U3_V << PCNT_CH1_POS_MODE_U3_S)
+#define PCNT_CH1_POS_MODE_U3_V  0x00000003
+#define PCNT_CH1_POS_MODE_U3_S  26
+
+/* PCNT_CH1_NEG_MODE_U3 : R/W; bitpos: [25:24]; default: 0;
+ * This register sets the behavior when the signal input of channel 1
+ * detects a negative edge.
+ *
+ * 1: Increment the counter;2: Decrement the counter;0, 3: No effect on
+ * counter
+ */
+
+#define PCNT_CH1_NEG_MODE_U3    0x00000003
+#define PCNT_CH1_NEG_MODE_U3_M  (PCNT_CH1_NEG_MODE_U3_V << PCNT_CH1_NEG_MODE_U3_S)
+#define PCNT_CH1_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH1_NEG_MODE_U3_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U3 : R/W; bitpos: [23:22]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is low.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_M  (PCNT_CH0_LCTRL_MODE_U3_V << PCNT_CH0_LCTRL_MODE_U3_S)
+#define PCNT_CH0_LCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U3_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U3 : R/W; bitpos: [21:20]; default: 0;
+ * This register configures how the CH3_POS_MODE/CH3_NEG_MODE settings will
+ * be modified when the control signal is high.
+ *
+ * 0: No modification;1: Invert behavior (increase -> decrease, decrease ->
+ * increase);2, 3: Inhibit counter modification
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U3    0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_M  (PCNT_CH0_HCTRL_MODE_U3_V << PCNT_CH0_HCTRL_MODE_U3_S)
+#define PCNT_CH0_HCTRL_MODE_U3_V  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U3_S  20
+
+/* PCNT_CH0_POS_MODE_U3 : R/W; bitpos: [19:18]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a positive edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_POS_MODE_U3    0x00000003
+#define PCNT_CH0_POS_MODE_U3_M  (PCNT_CH0_POS_MODE_U3_V << PCNT_CH0_POS_MODE_U3_S)
+#define PCNT_CH0_POS_MODE_U3_V  0x00000003
+#define PCNT_CH0_POS_MODE_U3_S  18
+
+/* PCNT_CH0_NEG_MODE_U3 : R/W; bitpos: [17:16]; default: 0;
+ * This register sets the behavior when the signal input of channel 0
+ * detects a negative edge.
+ *
+ * 1: Increase the counter;2: Decrease the counter;0, 3: No effect on counter
+ */
+
+#define PCNT_CH0_NEG_MODE_U3    0x00000003
+#define PCNT_CH0_NEG_MODE_U3_M  (PCNT_CH0_NEG_MODE_U3_V << PCNT_CH0_NEG_MODE_U3_S)
+#define PCNT_CH0_NEG_MODE_U3_V  0x00000003
+#define PCNT_CH0_NEG_MODE_U3_S  16
+
+/* PCNT_THR_THRES1_EN_U3 : R/W; bitpos: [15]; default: 0;
+ * This is the enable bit for unit 3's thres1 comparator.
+ */
+
+#define PCNT_THR_THRES1_EN_U3    (BIT(15))
+#define PCNT_THR_THRES1_EN_U3_M  (PCNT_THR_THRES1_EN_U3_V << PCNT_THR_THRES1_EN_U3_S)
+#define PCNT_THR_THRES1_EN_U3_V  0x00000001
+#define PCNT_THR_THRES1_EN_U3_S  15
+
+/* PCNT_THR_THRES0_EN_U3 : R/W; bitpos: [14]; default: 0;
+ * This is the enable bit for unit 3's thres0 comparator.
+ */
+
+#define PCNT_THR_THRES0_EN_U3    (BIT(14))
+#define PCNT_THR_THRES0_EN_U3_M  (PCNT_THR_THRES0_EN_U3_V << PCNT_THR_THRES0_EN_U3_S)
+#define PCNT_THR_THRES0_EN_U3_V  0x00000001
+#define PCNT_THR_THRES0_EN_U3_S  14
+
+/* PCNT_THR_L_LIM_EN_U3 : R/W; bitpos: [13]; default: 1;
+ * This is the enable bit for unit 3's thr_l_lim comparator.
+ */
+
+#define PCNT_THR_L_LIM_EN_U3    (BIT(13))
+#define PCNT_THR_L_LIM_EN_U3_M  (PCNT_THR_L_LIM_EN_U3_V << PCNT_THR_L_LIM_EN_U3_S)
+#define PCNT_THR_L_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_L_LIM_EN_U3_S  13
+
+/* PCNT_THR_H_LIM_EN_U3 : R/W; bitpos: [12]; default: 1;
+ * This is the enable bit for unit 3's thr_h_lim comparator.
+ */
+
+#define PCNT_THR_H_LIM_EN_U3    (BIT(12))
+#define PCNT_THR_H_LIM_EN_U3_M  (PCNT_THR_H_LIM_EN_U3_V << PCNT_THR_H_LIM_EN_U3_S)
+#define PCNT_THR_H_LIM_EN_U3_V  0x00000001
+#define PCNT_THR_H_LIM_EN_U3_S  12
+
+/* PCNT_THR_ZERO_EN_U3 : R/W; bitpos: [11]; default: 1;
+ * This is the enable bit for unit 3's zero comparator.
+ */
+
+#define PCNT_THR_ZERO_EN_U3    (BIT(11))
+#define PCNT_THR_ZERO_EN_U3_M  (PCNT_THR_ZERO_EN_U3_V << PCNT_THR_ZERO_EN_U3_S)
+#define PCNT_THR_ZERO_EN_U3_V  0x00000001
+#define PCNT_THR_ZERO_EN_U3_S  11
+
+/* PCNT_FILTER_EN_U3 : R/W; bitpos: [10]; default: 1;
+ * This is the enable bit for unit 3's input filter.
+ */
+
+#define PCNT_FILTER_EN_U3    (BIT(10))
+#define PCNT_FILTER_EN_U3_M  (PCNT_FILTER_EN_U3_V << PCNT_FILTER_EN_U3_S)
+#define PCNT_FILTER_EN_U3_V  0x00000001
+#define PCNT_FILTER_EN_U3_S  10
+
+/* PCNT_FILTER_THRES_U3 : R/W; bitpos: [9:0]; default: 16;
+ * This sets the maximum threshold, in APB_CLK cycles, for the filter.
+ *
+ * Any pulses with width less than this will be ignored when the filter is
+ * enabled.
+ */
+
+#define PCNT_FILTER_THRES_U3    0x000003ff
+#define PCNT_FILTER_THRES_U3_M  (PCNT_FILTER_THRES_U3_V << PCNT_FILTER_THRES_U3_S)
+#define PCNT_FILTER_THRES_U3_V  0x000003ff
+#define PCNT_FILTER_THRES_U3_S  0
+
+/* PCNT_U3_CONF1_REG register
+ * Configuration register 1 for unit 3
+ */
+
+#define PCNT_U3_CONF1_REG (DR_REG_PCNT_BASE + 0x28)
+
+/* PCNT_CNT_THRES1_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thres1 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES1_U3    0x0000ffff
+#define PCNT_CNT_THRES1_U3_M  (PCNT_CNT_THRES1_U3_V << PCNT_CNT_THRES1_U3_S)
+#define PCNT_CNT_THRES1_U3_V  0x0000ffff
+#define PCNT_CNT_THRES1_U3_S  16
+
+/* PCNT_CNT_THRES0_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thres0 value for unit 3.
+ */
+
+#define PCNT_CNT_THRES0_U3    0x0000ffff
+#define PCNT_CNT_THRES0_U3_M  (PCNT_CNT_THRES0_U3_V << PCNT_CNT_THRES0_U3_S)
+#define PCNT_CNT_THRES0_U3_V  0x0000ffff
+#define PCNT_CNT_THRES0_U3_S  0
+
+/* PCNT_U3_CONF2_REG register
+ * Configuration register 2 for unit 3
+ */
+
+#define PCNT_U3_CONF2_REG (DR_REG_PCNT_BASE + 0x2c)
+
+/* PCNT_CNT_L_LIM_U3 : R/W; bitpos: [31:16]; default: 0;
+ * This register is used to configure the thr_l_lim value for unit 3.
+ */
+
+#define PCNT_CNT_L_LIM_U3    0x0000ffff
+#define PCNT_CNT_L_LIM_U3_M  (PCNT_CNT_L_LIM_U3_V << PCNT_CNT_L_LIM_U3_S)
+#define PCNT_CNT_L_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_L_LIM_U3_S  16
+
+/* PCNT_CNT_H_LIM_U3 : R/W; bitpos: [15:0]; default: 0;
+ * This register is used to configure the thr_h_lim value for unit 3.
+ */
+
+#define PCNT_CNT_H_LIM_U3    0x0000ffff
+#define PCNT_CNT_H_LIM_U3_M  (PCNT_CNT_H_LIM_U3_V << PCNT_CNT_H_LIM_U3_S)
+#define PCNT_CNT_H_LIM_U3_V  0x0000ffff
+#define PCNT_CNT_H_LIM_U3_S  0
+
+#define PCNT_U4_CONF0_REG          (DR_REG_PCNT_BASE + 0x0030)
+
+/* PCNT_CH1_LCTRL_MODE_U4 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U4_M  ((PCNT_CH1_LCTRL_MODE_U4_V)<<(PCNT_CH1_LCTRL_MODE_U4_S))
+#define PCNT_CH1_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U4_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U4 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U4_M  ((PCNT_CH1_HCTRL_MODE_U4_V)<<(PCNT_CH1_HCTRL_MODE_U4_S))
+#define PCNT_CH1_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U4_S  28
+
+/* PCNT_CH1_POS_MODE_U4 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U4  0x00000003
+#define PCNT_CH1_POS_MODE_U4_M  ((PCNT_CH1_POS_MODE_U4_V)<<(PCNT_CH1_POS_MODE_U4_S))
+#define PCNT_CH1_POS_MODE_U4_V  0x3
+#define PCNT_CH1_POS_MODE_U4_S  26
+
+/* PCNT_CH1_NEG_MODE_U4 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U4  0x00000003
+#define PCNT_CH1_NEG_MODE_U4_M  ((PCNT_CH1_NEG_MODE_U4_V)<<(PCNT_CH1_NEG_MODE_U4_S))
+#define PCNT_CH1_NEG_MODE_U4_V  0x3
+#define PCNT_CH1_NEG_MODE_U4_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U4 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U4_M  ((PCNT_CH0_LCTRL_MODE_U4_V)<<(PCNT_CH0_LCTRL_MODE_U4_S))
+#define PCNT_CH0_LCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U4_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U4 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit4.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U4  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U4_M  ((PCNT_CH0_HCTRL_MODE_U4_V)<<(PCNT_CH0_HCTRL_MODE_U4_S))
+#define PCNT_CH0_HCTRL_MODE_U4_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U4_S  20
+
+/* PCNT_CH0_POS_MODE_U4 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit4.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U4  0x00000003
+#define PCNT_CH0_POS_MODE_U4_M  ((PCNT_CH0_POS_MODE_U4_V)<<(PCNT_CH0_POS_MODE_U4_S))
+#define PCNT_CH0_POS_MODE_U4_V  0x3
+#define PCNT_CH0_POS_MODE_U4_S  18
+
+/* PCNT_CH0_NEG_MODE_U4 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit4.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U4  0x00000003
+#define PCNT_CH0_NEG_MODE_U4_M  ((PCNT_CH0_NEG_MODE_U4_V)<<(PCNT_CH0_NEG_MODE_U4_S))
+#define PCNT_CH0_NEG_MODE_U4_V  0x3
+#define PCNT_CH0_NEG_MODE_U4_S  16
+
+/* PCNT_THR_THRES1_EN_U4 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U4  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U4_V  0x1
+#define PCNT_THR_THRES1_EN_U4_S  15
+
+/* PCNT_THR_THRES0_EN_U4 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U4  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U4_V  0x1
+#define PCNT_THR_THRES0_EN_U4_S  14
+
+/* PCNT_THR_L_LIM_EN_U4 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_l_lim  value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U4  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U4_V  0x1
+#define PCNT_THR_L_LIM_EN_U4_S  13
+
+/* PCNT_THR_H_LIM_EN_U4 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U4  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U4_V  0x1
+#define PCNT_THR_H_LIM_EN_U4_S  12
+
+/* PCNT_THR_ZERO_EN_U4 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit4's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U4  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U4_V  0x1
+#define PCNT_THR_ZERO_EN_U4_S  11
+
+/* PCNT_FILTER_EN_U4 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit4.
+ */
+
+#define PCNT_FILTER_EN_U4  (BIT(10))
+#define PCNT_FILTER_EN_U4_M  (BIT(10))
+#define PCNT_FILTER_EN_U4_V  0x1
+#define PCNT_FILTER_EN_U4_S  10
+
+/* PCNT_FILTER_THRES_U4 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit4.
+ */
+
+#define PCNT_FILTER_THRES_U4  0x000003FF
+#define PCNT_FILTER_THRES_U4_M  ((PCNT_FILTER_THRES_U4_V)<<(PCNT_FILTER_THRES_U4_S))
+#define PCNT_FILTER_THRES_U4_V  0x3FF
+#define PCNT_FILTER_THRES_U4_S  0
+
+#define PCNT_U4_CONF1_REG          (DR_REG_PCNT_BASE + 0x0034)
+
+/* PCNT_CNT_THRES1_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure thres1 value for unit4.
+ */
+
+#define PCNT_CNT_THRES1_U4  0x0000FFFF
+#define PCNT_CNT_THRES1_U4_M  ((PCNT_CNT_THRES1_U4_V)<<(PCNT_CNT_THRES1_U4_S))
+#define PCNT_CNT_THRES1_U4_V  0xFFFF
+#define PCNT_CNT_THRES1_U4_S  16
+
+/* PCNT_CNT_THRES0_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit4.
+ */
+
+#define PCNT_CNT_THRES0_U4  0x0000FFFF
+#define PCNT_CNT_THRES0_U4_M  ((PCNT_CNT_THRES0_U4_V)<<(PCNT_CNT_THRES0_U4_S))
+#define PCNT_CNT_THRES0_U4_V  0xFFFF
+#define PCNT_CNT_THRES0_U4_S  0
+
+#define PCNT_U4_CONF2_REG          (DR_REG_PCNT_BASE + 0x0038)
+
+/* PCNT_CNT_L_LIM_U4 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit4.
+ */
+
+#define PCNT_CNT_L_LIM_U4  0x0000FFFF
+#define PCNT_CNT_L_LIM_U4_M  ((PCNT_CNT_L_LIM_U4_V)<<(PCNT_CNT_L_LIM_U4_S))
+#define PCNT_CNT_L_LIM_U4_V  0xFFFF
+#define PCNT_CNT_L_LIM_U4_S  16
+
+/* PCNT_CNT_H_LIM_U4 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit4.
+ */
+
+#define PCNT_CNT_H_LIM_U4  0x0000FFFF
+#define PCNT_CNT_H_LIM_U4_M  ((PCNT_CNT_H_LIM_U4_V)<<(PCNT_CNT_H_LIM_U4_S))
+#define PCNT_CNT_H_LIM_U4_V  0xFFFF
+#define PCNT_CNT_H_LIM_U4_S  0
+
+#define PCNT_U5_CONF0_REG          (DR_REG_PCNT_BASE + 0x003c)
+
+/* PCNT_CH1_LCTRL_MODE_U5 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U5_M  ((PCNT_CH1_LCTRL_MODE_U5_V)<<(PCNT_CH1_LCTRL_MODE_U5_S))
+#define PCNT_CH1_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U5_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U5 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U5_M  ((PCNT_CH1_HCTRL_MODE_U5_V)<<(PCNT_CH1_HCTRL_MODE_U5_S))
+#define PCNT_CH1_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U5_S  28
+
+/* PCNT_CH1_POS_MODE_U5 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U5  0x00000003
+#define PCNT_CH1_POS_MODE_U5_M  ((PCNT_CH1_POS_MODE_U5_V)<<(PCNT_CH1_POS_MODE_U5_S))
+#define PCNT_CH1_POS_MODE_U5_V  0x3
+#define PCNT_CH1_POS_MODE_U5_S  26
+
+/* PCNT_CH1_NEG_MODE_U5 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U5  0x00000003
+#define PCNT_CH1_NEG_MODE_U5_M  ((PCNT_CH1_NEG_MODE_U5_V)<<(PCNT_CH1_NEG_MODE_U5_S))
+#define PCNT_CH1_NEG_MODE_U5_V  0x3
+#define PCNT_CH1_NEG_MODE_U5_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U5 : R/W ;bitpos:[23:22] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's low
+ * control signal for unit5.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U5_M  ((PCNT_CH0_LCTRL_MODE_U5_V)<<(PCNT_CH0_LCTRL_MODE_U5_S))
+#define PCNT_CH0_LCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U5_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U5 : R/W ;bitpos:[21:20] ;default: 2'd0 ; */
+
+/* Description: This register is used to control the mode of channel0's high
+ * control signal for unit5.
+ * 0:increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U5  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U5_M  ((PCNT_CH0_HCTRL_MODE_U5_V)<<(PCNT_CH0_HCTRL_MODE_U5_S))
+#define PCNT_CH0_HCTRL_MODE_U5_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U5_S  20
+
+/* PCNT_CH0_POS_MODE_U5 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit5.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U5  0x00000003
+#define PCNT_CH0_POS_MODE_U5_M  ((PCNT_CH0_POS_MODE_U5_V)<<(PCNT_CH0_POS_MODE_U5_S))
+#define PCNT_CH0_POS_MODE_U5_V  0x3
+#define PCNT_CH0_POS_MODE_U5_S  18
+
+/* PCNT_CH0_NEG_MODE_U5 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit5.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U5  0x00000003
+#define PCNT_CH0_NEG_MODE_U5_M  ((PCNT_CH0_NEG_MODE_U5_V)<<(PCNT_CH0_NEG_MODE_U5_S))
+#define PCNT_CH0_NEG_MODE_U5_V  0x3
+#define PCNT_CH0_NEG_MODE_U5_S  16
+
+/* PCNT_THR_THRES1_EN_U5 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U5  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U5_V  0x1
+#define PCNT_THR_THRES1_EN_U5_S  15
+
+/* PCNT_THR_THRES0_EN_U5 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U5  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U5_V  0x1
+#define PCNT_THR_THRES0_EN_U5_S  14
+
+/* PCNT_THR_L_LIM_EN_U5 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U5  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U5_V  0x1
+#define PCNT_THR_L_LIM_EN_U5_S  13
+
+/* PCNT_THR_H_LIM_EN_U5 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U5  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U5_V  0x1
+#define PCNT_THR_H_LIM_EN_U5_S  12
+
+/* PCNT_THR_ZERO_EN_U5 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit5's count
+ * with 0 value.
+ */
+
+#define PCNT_THR_ZERO_EN_U5  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U5_V  0x1
+#define PCNT_THR_ZERO_EN_U5_S  11
+
+/* PCNT_FILTER_EN_U5 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit5.
+ */
+
+#define PCNT_FILTER_EN_U5  (BIT(10))
+#define PCNT_FILTER_EN_U5_M  (BIT(10))
+#define PCNT_FILTER_EN_U5_V  0x1
+#define PCNT_FILTER_EN_U5_S  10
+
+/* PCNT_FILTER_THRES_U5 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit5.
+ */
+
+#define PCNT_FILTER_THRES_U5  0x000003FF
+#define PCNT_FILTER_THRES_U5_M  ((PCNT_FILTER_THRES_U5_V)<<(PCNT_FILTER_THRES_U5_S))
+#define PCNT_FILTER_THRES_U5_V  0x3FF
+#define PCNT_FILTER_THRES_U5_S  0
+
+#define PCNT_U5_CONF1_REG          (DR_REG_PCNT_BASE + 0x0040)
+
+/* PCNT_CNT_THRES1_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit5.
+ */
+
+#define PCNT_CNT_THRES1_U5  0x0000FFFF
+#define PCNT_CNT_THRES1_U5_M  ((PCNT_CNT_THRES1_U5_V)<<(PCNT_CNT_THRES1_U5_S))
+#define PCNT_CNT_THRES1_U5_V  0xFFFF
+#define PCNT_CNT_THRES1_U5_S  16
+
+/* PCNT_CNT_THRES0_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit5.
+ */
+
+#define PCNT_CNT_THRES0_U5  0x0000FFFF
+#define PCNT_CNT_THRES0_U5_M  ((PCNT_CNT_THRES0_U5_V)<<(PCNT_CNT_THRES0_U5_S))
+#define PCNT_CNT_THRES0_U5_V  0xFFFF
+#define PCNT_CNT_THRES0_U5_S  0
+
+#define PCNT_U5_CONF2_REG          (DR_REG_PCNT_BASE + 0x0044)
+
+/* PCNT_CNT_L_LIM_U5 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit5.
+ */
+
+#define PCNT_CNT_L_LIM_U5  0x0000FFFF
+#define PCNT_CNT_L_LIM_U5_M  ((PCNT_CNT_L_LIM_U5_V)<<(PCNT_CNT_L_LIM_U5_S))
+#define PCNT_CNT_L_LIM_U5_V  0xFFFF
+#define PCNT_CNT_L_LIM_U5_S  16
+
+/* PCNT_CNT_H_LIM_U5 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit5.
+ */
+
+#define PCNT_CNT_H_LIM_U5  0x0000FFFF
+#define PCNT_CNT_H_LIM_U5_M  ((PCNT_CNT_H_LIM_U5_V)<<(PCNT_CNT_H_LIM_U5_S))
+#define PCNT_CNT_H_LIM_U5_V  0xFFFF
+#define PCNT_CNT_H_LIM_U5_S  0
+
+#define PCNT_U6_CONF0_REG          (DR_REG_PCNT_BASE + 0x0048)
+
+/* PCNT_CH1_LCTRL_MODE_U6 : R/W ;bitpos:[31:30] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * low control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U6_M  ((PCNT_CH1_LCTRL_MODE_U6_V)<<(PCNT_CH1_LCTRL_MODE_U6_S))
+#define PCNT_CH1_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U6_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U6 : R/W ;bitpos:[29:28] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U6_M  ((PCNT_CH1_HCTRL_MODE_U6_V)<<(PCNT_CH1_HCTRL_MODE_U6_S))
+#define PCNT_CH1_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U6_S  28
+
+/* PCNT_CH1_POS_MODE_U6 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U6  0x00000003
+#define PCNT_CH1_POS_MODE_U6_M  ((PCNT_CH1_POS_MODE_U6_V)<<(PCNT_CH1_POS_MODE_U6_S))
+#define PCNT_CH1_POS_MODE_U6_V  0x3
+#define PCNT_CH1_POS_MODE_U6_S  26
+
+/* PCNT_CH1_NEG_MODE_U6 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's
+ * input negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U6  0x00000003
+#define PCNT_CH1_NEG_MODE_U6_M  ((PCNT_CH1_NEG_MODE_U6_V)<<(PCNT_CH1_NEG_MODE_U6_S))
+#define PCNT_CH1_NEG_MODE_U6_V  0x3
+#define PCNT_CH1_NEG_MODE_U6_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U6 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U6_M  ((PCNT_CH0_LCTRL_MODE_U6_V)<<(PCNT_CH0_LCTRL_MODE_U6_S))
+#define PCNT_CH0_LCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U6_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U6 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * high control signal for unit6.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U6  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U6_M  ((PCNT_CH0_HCTRL_MODE_U6_V)<<(PCNT_CH0_HCTRL_MODE_U6_S))
+#define PCNT_CH0_HCTRL_MODE_U6_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U6_S  20
+
+/* PCNT_CH0_POS_MODE_U6 : R/W ;bitpos:[19:18] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit6.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U6  0x00000003
+#define PCNT_CH0_POS_MODE_U6_M  ((PCNT_CH0_POS_MODE_U6_V)<<(PCNT_CH0_POS_MODE_U6_S))
+#define PCNT_CH0_POS_MODE_U6_V  0x3
+#define PCNT_CH0_POS_MODE_U6_S  18
+
+/* PCNT_CH0_NEG_MODE_U6 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * negedge signal for unit6.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U6  0x00000003
+#define PCNT_CH0_NEG_MODE_U6_M  ((PCNT_CH0_NEG_MODE_U6_V)<<(PCNT_CH0_NEG_MODE_U6_S))
+#define PCNT_CH0_NEG_MODE_U6_V  0x3
+#define PCNT_CH0_NEG_MODE_U6_S  16
+
+/* PCNT_THR_THRES1_EN_U6 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit6's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U6  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U6_V  0x1
+#define PCNT_THR_THRES1_EN_U6_S  15
+
+/* PCNT_THR_THRES0_EN_U6 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U6  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U6_V  0x1
+#define PCNT_THR_THRES0_EN_U6_S  14
+
+/* PCNT_THR_L_LIM_EN_U6 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U6  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U6_V  0x1
+#define PCNT_THR_L_LIM_EN_U6_S  13
+
+/* PCNT_THR_H_LIM_EN_U6 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit6's count with
+ * thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U6  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U6_V  0x1
+#define PCNT_THR_H_LIM_EN_U6_S  12
+
+/* PCNT_THR_ZERO_EN_U6 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit6's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U6  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U6_V  0x1
+#define PCNT_THR_ZERO_EN_U6_S  11
+
+/* PCNT_FILTER_EN_U6 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit6.
+ */
+
+#define PCNT_FILTER_EN_U6  (BIT(10))
+#define PCNT_FILTER_EN_U6_M  (BIT(10))
+#define PCNT_FILTER_EN_U6_V  0x1
+#define PCNT_FILTER_EN_U6_S  10
+
+/* PCNT_FILTER_THRES_U6 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is
+ * smaller than this value for unit6.
+ */
+
+#define PCNT_FILTER_THRES_U6  0x000003FF
+#define PCNT_FILTER_THRES_U6_M  ((PCNT_FILTER_THRES_U6_V)<<(PCNT_FILTER_THRES_U6_S))
+#define PCNT_FILTER_THRES_U6_V  0x3FF
+#define PCNT_FILTER_THRES_U6_S  0
+
+#define PCNT_U6_CONF1_REG          (DR_REG_PCNT_BASE + 0x004c)
+
+/* PCNT_CNT_THRES1_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit6.
+ */
+
+#define PCNT_CNT_THRES1_U6  0x0000FFFF
+#define PCNT_CNT_THRES1_U6_M  ((PCNT_CNT_THRES1_U6_V)<<(PCNT_CNT_THRES1_U6_S))
+#define PCNT_CNT_THRES1_U6_V  0xFFFF
+#define PCNT_CNT_THRES1_U6_S  16
+
+/* PCNT_CNT_THRES0_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit6.
+ */
+
+#define PCNT_CNT_THRES0_U6  0x0000FFFF
+#define PCNT_CNT_THRES0_U6_M  ((PCNT_CNT_THRES0_U6_V)<<(PCNT_CNT_THRES0_U6_S))
+#define PCNT_CNT_THRES0_U6_V  0xFFFF
+#define PCNT_CNT_THRES0_U6_S  0
+
+#define PCNT_U6_CONF2_REG          (DR_REG_PCNT_BASE + 0x0050)
+
+/* PCNT_CNT_L_LIM_U6 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit6.
+ */
+
+#define PCNT_CNT_L_LIM_U6  0x0000FFFF
+#define PCNT_CNT_L_LIM_U6_M  ((PCNT_CNT_L_LIM_U6_V)<<(PCNT_CNT_L_LIM_U6_S))
+#define PCNT_CNT_L_LIM_U6_V  0xFFFF
+#define PCNT_CNT_L_LIM_U6_S  16
+
+/* PCNT_CNT_H_LIM_U6 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit6.
+ */
+
+#define PCNT_CNT_H_LIM_U6  0x0000FFFF
+#define PCNT_CNT_H_LIM_U6_M  ((PCNT_CNT_H_LIM_U6_V)<<(PCNT_CNT_H_LIM_U6_S))
+#define PCNT_CNT_H_LIM_U6_V  0xFFFF
+#define PCNT_CNT_H_LIM_U6_S  0
+
+#define PCNT_U7_CONF0_REG          (DR_REG_PCNT_BASE + 0x0054)
+
+/* PCNT_CH1_LCTRL_MODE_U7 : R/W ;bitpos:[31:30] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_LCTRL_MODE_U7_M  ((PCNT_CH1_LCTRL_MODE_U7_V)<<(PCNT_CH1_LCTRL_MODE_U7_S))
+#define PCNT_CH1_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_LCTRL_MODE_U7_S  30
+
+/* PCNT_CH1_HCTRL_MODE_U7 : R/W ;bitpos:[29:28] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel1's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH1_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH1_HCTRL_MODE_U7_M  ((PCNT_CH1_HCTRL_MODE_U7_V)<<(PCNT_CH1_HCTRL_MODE_U7_S))
+#define PCNT_CH1_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH1_HCTRL_MODE_U7_S  28
+
+/* PCNT_CH1_POS_MODE_U7 : R/W ;bitpos:[27:26] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2:decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_POS_MODE_U7  0x00000003
+#define PCNT_CH1_POS_MODE_U7_M  ((PCNT_CH1_POS_MODE_U7_V)<<(PCNT_CH1_POS_MODE_U7_S))
+#define PCNT_CH1_POS_MODE_U7_V  0x3
+#define PCNT_CH1_POS_MODE_U7_S  26
+
+/* PCNT_CH1_NEG_MODE_U7 : R/W ;bitpos:[25:24] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel1's input
+ * negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH1_NEG_MODE_U7  0x00000003
+#define PCNT_CH1_NEG_MODE_U7_M  ((PCNT_CH1_NEG_MODE_U7_V)<<(PCNT_CH1_NEG_MODE_U7_S))
+#define PCNT_CH1_NEG_MODE_U7_V  0x3
+#define PCNT_CH1_NEG_MODE_U7_S  24
+
+/* PCNT_CH0_LCTRL_MODE_U7 : R/W ;bitpos:[23:22] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's low
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_LCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_LCTRL_MODE_U7_M  ((PCNT_CH0_LCTRL_MODE_U7_V)<<(PCNT_CH0_LCTRL_MODE_U7_S))
+#define PCNT_CH0_LCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_LCTRL_MODE_U7_S  22
+
+/* PCNT_CH0_HCTRL_MODE_U7 : R/W ;bitpos:[21:20] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's high
+ * control signal for unit7.
+ * 0: increase when control signal is low
+ * 1: decrease when control signal is high
+ * others: forbidden
+ */
+
+#define PCNT_CH0_HCTRL_MODE_U7  0x00000003
+#define PCNT_CH0_HCTRL_MODE_U7_M  ((PCNT_CH0_HCTRL_MODE_U7_V)<<(PCNT_CH0_HCTRL_MODE_U7_S))
+#define PCNT_CH0_HCTRL_MODE_U7_V  0x3
+#define PCNT_CH0_HCTRL_MODE_U7_S  20
+
+/* PCNT_CH0_POS_MODE_U7 : R/W ;bitpos:[19:18] ;
+ * default: 0 ;
+ * Description: This register is used to control the mode of channel0's input
+ * posedge signal for unit7.
+ * 1: increase at the posedge of input signal
+ * 2: decrease at the posedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_POS_MODE_U7  0x00000003
+#define PCNT_CH0_POS_MODE_U7_M  ((PCNT_CH0_POS_MODE_U7_V)<<(PCNT_CH0_POS_MODE_U7_S))
+#define PCNT_CH0_POS_MODE_U7_V  0x3
+#define PCNT_CH0_POS_MODE_U7_S  18
+
+/* PCNT_CH0_NEG_MODE_U7 : R/W ;bitpos:[17:16] ;default: 2'd0 ;
+ * Description: This register is used to control the mode of channel0's
+ * input negedge signal for unit7.
+ * 1: increase at the negedge of input signal
+ * 2: decrease at the negedge of input signal
+ * others: forbidden
+ */
+
+#define PCNT_CH0_NEG_MODE_U7  0x00000003
+#define PCNT_CH0_NEG_MODE_U7_M  ((PCNT_CH0_NEG_MODE_U7_V)<<(PCNT_CH0_NEG_MODE_U7_S))
+#define PCNT_CH0_NEG_MODE_U7_V  0x3
+#define PCNT_CH0_NEG_MODE_U7_S  16
+
+/* PCNT_THR_THRES1_EN_U7 : R/W ;bitpos:[15] ;default: 1'b0 ;
+ * Description: This is the enable bit for  comparing  unit7's count with
+ * thres1 value.
+ */
+
+#define PCNT_THR_THRES1_EN_U7  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_M  (BIT(15))
+#define PCNT_THR_THRES1_EN_U7_V  0x1
+#define PCNT_THR_THRES1_EN_U7_S  15
+
+/* PCNT_THR_THRES0_EN_U7 : R/W ;bitpos:[14] ;default: 1'b0 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thres0 value.
+ */
+
+#define PCNT_THR_THRES0_EN_U7  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_M  (BIT(14))
+#define PCNT_THR_THRES0_EN_U7_V  0x1
+#define PCNT_THR_THRES0_EN_U7_S  14
+
+/* PCNT_THR_L_LIM_EN_U7 : R/W ;bitpos:[13] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with
+ * thr_l_lim value.
+ */
+
+#define PCNT_THR_L_LIM_EN_U7  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_M  (BIT(13))
+#define PCNT_THR_L_LIM_EN_U7_V  0x1
+#define PCNT_THR_L_LIM_EN_U7_S  13
+
+/* PCNT_THR_H_LIM_EN_U7 : R/W ;bitpos:[12] ;default: 1'b1 ;
+ * Description: This is the enable bit for  comparing unit7's count
+ * with thr_h_lim value.
+ */
+
+#define PCNT_THR_H_LIM_EN_U7  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_M  (BIT(12))
+#define PCNT_THR_H_LIM_EN_U7_V  0x1
+#define PCNT_THR_H_LIM_EN_U7_S  12
+
+/* PCNT_THR_ZERO_EN_U7 : R/W ;bitpos:[11] ;default: 1'b1 ;
+ * Description: This is the enable bit for comparing unit7's count with 0
+ * value.
+ */
+
+#define PCNT_THR_ZERO_EN_U7  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_M  (BIT(11))
+#define PCNT_THR_ZERO_EN_U7_V  0x1
+#define PCNT_THR_ZERO_EN_U7_S  11
+
+/* PCNT_FILTER_EN_U7 : R/W ;bitpos:[10] ;default: 1'b1 ;
+ * Description: This is the enable bit for filtering input signals for unit7.
+ */
+
+#define PCNT_FILTER_EN_U7  (BIT(10))
+#define PCNT_FILTER_EN_U7_M  (BIT(10))
+#define PCNT_FILTER_EN_U7_V  0x1
+#define PCNT_FILTER_EN_U7_S  10
+
+/* PCNT_FILTER_THRES_U7 : R/W ;bitpos:[9:0] ;default: 10'h10 ;
+ * Description: This register is used to filter pluse whose width is smaller
+ * than this value for unit7.
+ */
+
+#define PCNT_FILTER_THRES_U7  0x000003FF
+#define PCNT_FILTER_THRES_U7_M  ((PCNT_FILTER_THRES_U7_V)<<(PCNT_FILTER_THRES_U7_S))
+#define PCNT_FILTER_THRES_U7_V  0x3FF
+#define PCNT_FILTER_THRES_U7_S  0
+
+#define PCNT_U7_CONF1_REG          (DR_REG_PCNT_BASE + 0x0058)
+
+/* PCNT_CNT_THRES1_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to configure  thres1 value for unit7.
+ */
+
+#define PCNT_CNT_THRES1_U7  0x0000FFFF
+#define PCNT_CNT_THRES1_U7_M  ((PCNT_CNT_THRES1_U7_V)<<(PCNT_CNT_THRES1_U7_S))
+#define PCNT_CNT_THRES1_U7_V  0xFFFF
+#define PCNT_CNT_THRES1_U7_S  16
+
+/* PCNT_CNT_THRES0_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thres0 value for unit7.
+ */
+
+#define PCNT_CNT_THRES0_U7  0x0000FFFF
+#define PCNT_CNT_THRES0_U7_M  ((PCNT_CNT_THRES0_U7_V)<<(PCNT_CNT_THRES0_U7_S))
+#define PCNT_CNT_THRES0_U7_V  0xFFFF
+#define PCNT_CNT_THRES0_U7_S  0
+
+#define PCNT_U7_CONF2_REG          (DR_REG_PCNT_BASE + 0x005c)
+
+/* PCNT_CNT_L_LIM_U7 : R/W ;bitpos:[31:16] ;default: 10'h0 ;
+ * Description: This register is used to confiugre thr_l_lim value for unit7.
+ */
+
+#define PCNT_CNT_L_LIM_U7  0x0000FFFF
+#define PCNT_CNT_L_LIM_U7_M  ((PCNT_CNT_L_LIM_U7_V)<<(PCNT_CNT_L_LIM_U7_S))
+#define PCNT_CNT_L_LIM_U7_V  0xFFFF
+#define PCNT_CNT_L_LIM_U7_S  16
+
+/* PCNT_CNT_H_LIM_U7 : R/W ;bitpos:[15:0] ;default: 10'h0 ;
+ * Description: This register is used to configure thr_h_lim value for unit7.
+ */
+
+#define PCNT_CNT_H_LIM_U7  0x0000FFFF
+#define PCNT_CNT_H_LIM_U7_M  ((PCNT_CNT_H_LIM_U7_V)<<(PCNT_CNT_H_LIM_U7_S))
+#define PCNT_CNT_H_LIM_U7_V  0xFFFF
+#define PCNT_CNT_H_LIM_U7_S  0
+
+#define PCNT_U0_CNT_REG          (DR_REG_PCNT_BASE + 0x0060)
+
+/* PCNT_PLUS_CNT_U0 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit0.
+ */
+
+#define PCNT_PLUS_CNT_U0  0x0000FFFF
+#define PCNT_PLUS_CNT_U0_M  ((PCNT_PLUS_CNT_U0_V)<<(PCNT_PLUS_CNT_U0_S))
+#define PCNT_PLUS_CNT_U0_V  0xFFFF
+#define PCNT_PLUS_CNT_U0_S  0
+
+#define PCNT_U1_CNT_REG          (DR_REG_PCNT_BASE + 0x0064)
+
+/* PCNT_PLUS_CNT_U1 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit1.
+ */
+
+#define PCNT_PLUS_CNT_U1  0x0000FFFF
+#define PCNT_PLUS_CNT_U1_M  ((PCNT_PLUS_CNT_U1_V)<<(PCNT_PLUS_CNT_U1_S))
+#define PCNT_PLUS_CNT_U1_V  0xFFFF
+#define PCNT_PLUS_CNT_U1_S  0
+
+#define PCNT_U2_CNT_REG          (DR_REG_PCNT_BASE + 0x0068)
+
+/* PCNT_PLUS_CNT_U2 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit2.
+ */
+
+#define PCNT_PLUS_CNT_U2  0x0000FFFF
+#define PCNT_PLUS_CNT_U2_M  ((PCNT_PLUS_CNT_U2_V)<<(PCNT_PLUS_CNT_U2_S))
+#define PCNT_PLUS_CNT_U2_V  0xFFFF
+#define PCNT_PLUS_CNT_U2_S  0
+
+#define PCNT_U3_CNT_REG          (DR_REG_PCNT_BASE + 0x006c)
+
+/* PCNT_PLUS_CNT_U3 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit3.
+ */
+
+#define PCNT_PLUS_CNT_U3  0x0000FFFF
+#define PCNT_PLUS_CNT_U3_M  ((PCNT_PLUS_CNT_U3_V)<<(PCNT_PLUS_CNT_U3_S))
+#define PCNT_PLUS_CNT_U3_V  0xFFFF
+#define PCNT_PLUS_CNT_U3_S  0
+
+#define PCNT_U4_CNT_REG          (DR_REG_PCNT_BASE + 0x0070)
+
+/* PCNT_PLUS_CNT_U4 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit4.
+ */
+
+#define PCNT_PLUS_CNT_U4  0x0000FFFF
+#define PCNT_PLUS_CNT_U4_M  ((PCNT_PLUS_CNT_U4_V)<<(PCNT_PLUS_CNT_U4_S))
+#define PCNT_PLUS_CNT_U4_V  0xFFFF
+#define PCNT_PLUS_CNT_U4_S  0
+
+#define PCNT_U5_CNT_REG          (DR_REG_PCNT_BASE + 0x0074)
+
+/* PCNT_PLUS_CNT_U5 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit5.
+ */
+
+#define PCNT_PLUS_CNT_U5  0x0000FFFF
+#define PCNT_PLUS_CNT_U5_M  ((PCNT_PLUS_CNT_U5_V)<<(PCNT_PLUS_CNT_U5_S))
+#define PCNT_PLUS_CNT_U5_V  0xFFFF
+#define PCNT_PLUS_CNT_U5_S  0
+
+#define PCNT_U6_CNT_REG          (DR_REG_PCNT_BASE + 0x0078)
+
+/* PCNT_PLUS_CNT_U6 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit6.
+ */
+
+#define PCNT_PLUS_CNT_U6  0x0000FFFF
+#define PCNT_PLUS_CNT_U6_M  ((PCNT_PLUS_CNT_U6_V)<<(PCNT_PLUS_CNT_U6_S))
+#define PCNT_PLUS_CNT_U6_V  0xFFFF
+#define PCNT_PLUS_CNT_U6_S  0
+
+#define PCNT_U7_CNT_REG          (DR_REG_PCNT_BASE + 0x007c)
+
+/* PCNT_PLUS_CNT_U7 : RO ;bitpos:[15:0] ;default: 16'h0 ;
+ * Description: This register stores the current pulse count value for unit7.
+ */
+
+#define PCNT_PLUS_CNT_U7  0x0000FFFF
+#define PCNT_PLUS_CNT_U7_M  ((PCNT_PLUS_CNT_U7_V)<<(PCNT_PLUS_CNT_U7_S))
+#define PCNT_PLUS_CNT_U7_V  0xFFFF
+#define PCNT_PLUS_CNT_U7_S  0
+
+#define PCNT_INT_RAW_REG          (DR_REG_PCNT_BASE + 0x0080)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_RAW : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_RAW_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_RAW : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_RAW_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_RAW : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_RAW_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_RAW : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_RAW_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_RAW : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_RAW_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_RAW : RO ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_RAW_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_RAW : RO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_RAW_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_RAW : RO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the interrupt raw bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_RAW_S  0
+
+#define PCNT_INT_ST_REG          (DR_REG_PCNT_BASE + 0x0084)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ST : RO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ST  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ST_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ST : RO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ST  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ST_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ST : RO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ST  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ST_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ST : RO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ST  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ST_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ST : RO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt status bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ST  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ST_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ST : RO; bitpos: [2]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U2_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ST    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_M  (PCNT_CNT_THR_EVENT_U2_INT_ST_V << PCNT_CNT_THR_EVENT_U2_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_ST_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ST : RO; bitpos: [1]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U1_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ST    (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_M  (PCNT_CNT_THR_EVENT_U1_INT_ST_V << PCNT_CNT_THR_EVENT_U1_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U1_INT_ST_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ST : RO; bitpos: [0]; default: 0;
+ * The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U0_INT
+ * interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ST    (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_M  (PCNT_CNT_THR_EVENT_U0_INT_ST_V << PCNT_CNT_THR_EVENT_U0_INT_ST_S)
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U0_INT_ST_S  0
+
+/* PCNT_INT_ENA_REG register
+ * Interrupt enable register
+ */
+
+#define PCNT_INT_ENA_REG          (DR_REG_PCNT_BASE + 0x0088)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_ENA : R/W ;bitpos:[7] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel7 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_ENA_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_ENA : R/W ;bitpos:[6] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel6 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_ENA_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_ENA : R/W ;bitpos:[5] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel5 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_ENA_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_ENA : R/W ;bitpos:[4] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel4 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_ENA_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_ENA : R/W ;bitpos:[3] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel3 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_ENA_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_ENA : R/W ;bitpos:[2] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel2 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_M  (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U2_INT_ENA_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_ENA : R/W ;bitpos:[1] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel1 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_ENA_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_ENA : R/W ;bitpos:[0] ;default: 1'b0 ;
+ * Description: This is the  interrupt enable bit for channel0 event.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_ENA_S  0
+
+#define PCNT_INT_CLR_REG          (DR_REG_PCNT_BASE + 0x008c)
+
+/* PCNT_CNT_THR_EVENT_U7_INT_CLR : WO ;bitpos:[7] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel7 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_M  (BIT(7))
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U7_INT_CLR_S  7
+
+/* PCNT_CNT_THR_EVENT_U6_INT_CLR : WO ;bitpos:[6] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel6 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_M  (BIT(6))
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U6_INT_CLR_S  6
+
+/* PCNT_CNT_THR_EVENT_U5_INT_CLR : WO ;bitpos:[5] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel5 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_M  (BIT(5))
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U5_INT_CLR_S  5
+
+/* PCNT_CNT_THR_EVENT_U4_INT_CLR : WO ;bitpos:[4] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel4 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_M  (BIT(4))
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U4_INT_CLR_S  4
+
+/* PCNT_CNT_THR_EVENT_U3_INT_CLR : WO ;bitpos:[3] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel3 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_M  (BIT(3))
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U3_INT_CLR_S  3
+
+/* PCNT_CNT_THR_EVENT_U2_INT_CLR : WO; bitpos: [2]; default: 0;
+ * Set this bit to clear the PCNT_CNT_THR_EVENT_U2_INT interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR    (BIT(2))
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_M  (PCNT_CNT_THR_EVENT_U2_INT_CLR_V << PCNT_CNT_THR_EVENT_U2_INT_CLR_S)
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_V  0x00000001
+#define PCNT_CNT_THR_EVENT_U2_INT_CLR_S  2
+
+/* PCNT_CNT_THR_EVENT_U1_INT_CLR : WO ;bitpos:[1] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel1 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_M  (BIT(1))
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U1_INT_CLR_S  1
+
+/* PCNT_CNT_THR_EVENT_U0_INT_CLR : WO ;bitpos:[0] ;default: 1'b0 ;
+ * Description: Set this bit to clear channel0 event interrupt.
+ */
+
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_M  (BIT(0))
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_V  0x1
+#define PCNT_CNT_THR_EVENT_U0_INT_CLR_S  0
+
+#define PCNT_U0_STATUS_REG          (DR_REG_PCNT_BASE + 0x0090)
+
+/* PCNT_CORE_STATUS_U0 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U0  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_M  ((PCNT_CORE_STATUS_U0_V)<<(PCNT_CORE_STATUS_U0_S))
+#define PCNT_CORE_STATUS_U0_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U0_S  0
+
+/* 0: positive value to zero;
+ * 1: negative value to zero;
+ * 2: counter value negative;
+ * 3: counter value positive
+ */
+
+#define PCNT_STATUS_CNT_MODE    0x3
+#define PCNT_STATUS_CNT_MODE_M  ((PCNT_STATUS_CNT_MODE_V)<<(PCNT_STATUS_CNT_MODE_S))
+#define PCNT_STATUS_CNT_MODE_V  0x3
+#define PCNT_STATUS_CNT_MODE_S  0
+
+/* counter value equals to thresh1 */
+
+#define PCNT_STATUS_THRES1    BIT(2)
+#define PCNT_STATUS_THRES1_M  BIT(2)
+#define PCNT_STATUS_THRES1_V  0x1
+#define PCNT_STATUS_THRES1_S  2
+
+/* counter value equals to thresh0 */
+
+#define PCNT_STATUS_THRES0    BIT(3)
+#define PCNT_STATUS_THRES0_M  BIT(3)
+#define PCNT_STATUS_THRES0_V  0x1
+#define PCNT_STATUS_THRES0_S  3
+
+/* counter value reaches h_lim */
+
+#define PCNT_STATUS_L_LIM    BIT(4)
+#define PCNT_STATUS_L_LIM_M  BIT(4)
+#define PCNT_STATUS_L_LIM_V  0x1
+#define PCNT_STATUS_L_LIM_S  4
+
+/* counter value reaches l_lim */
+
+#define PCNT_STATUS_H_LIM    BIT(5)
+#define PCNT_STATUS_H_LIM_M  BIT(5)
+#define PCNT_STATUS_H_LIM_V  0x1
+#define PCNT_STATUS_H_LIM_S  5
+
+/* counter value equals to zero */
+
+#define PCNT_STATUS_ZERO    BIT(6)
+#define PCNT_STATUS_ZERO_M  BIT(6)
+#define PCNT_STATUS_ZERO_V  0x1
+#define PCNT_STATUS_ZERO_S  6
+
+#define PCNT_U1_STATUS_REG          (DR_REG_PCNT_BASE + 0x0094)
+
+/* PCNT_CORE_STATUS_U1 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U1  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_M  ((PCNT_CORE_STATUS_U1_V)<<(PCNT_CORE_STATUS_U1_S))
+#define PCNT_CORE_STATUS_U1_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U1_S  0
+
+#define PCNT_U2_STATUS_REG          (DR_REG_PCNT_BASE + 0x0098)
+
+/* PCNT_CORE_STATUS_U2 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U2  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_M  ((PCNT_CORE_STATUS_U2_V)<<(PCNT_CORE_STATUS_U2_S))
+#define PCNT_CORE_STATUS_U2_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U2_S  0
+
+#define PCNT_U3_STATUS_REG          (DR_REG_PCNT_BASE + 0x009c)
+
+/* PCNT_CORE_STATUS_U3 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U3  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_M  ((PCNT_CORE_STATUS_U3_V)<<(PCNT_CORE_STATUS_U3_S))
+#define PCNT_CORE_STATUS_U3_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U3_S  0
+
+#define PCNT_U4_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a0)
+/* PCNT_CORE_STATUS_U4 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U4  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_M  ((PCNT_CORE_STATUS_U4_V)<<(PCNT_CORE_STATUS_U4_S))
+#define PCNT_CORE_STATUS_U4_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U4_S  0
+
+#define PCNT_U5_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a4)
+/* PCNT_CORE_STATUS_U5 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U5  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_M  ((PCNT_CORE_STATUS_U5_V)<<(PCNT_CORE_STATUS_U5_S))
+#define PCNT_CORE_STATUS_U5_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U5_S  0
+
+#define PCNT_U6_STATUS_REG          (DR_REG_PCNT_BASE + 0x00a8)
+/* PCNT_CORE_STATUS_U6 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+/* Description: */
+
+#define PCNT_CORE_STATUS_U6  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_M  ((PCNT_CORE_STATUS_U6_V)<<(PCNT_CORE_STATUS_U6_S))
+#define PCNT_CORE_STATUS_U6_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U6_S  0
+
+#define PCNT_U7_STATUS_REG          (DR_REG_PCNT_BASE + 0x00ac)
+
+/* PCNT_CORE_STATUS_U7 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define PCNT_CORE_STATUS_U7  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_M  ((PCNT_CORE_STATUS_U7_V)<<(PCNT_CORE_STATUS_U7_S))
+#define PCNT_CORE_STATUS_U7_V  0xFFFFFFFF
+#define PCNT_CORE_STATUS_U7_S  0
+
+#define PCNT_CTRL_REG          (DR_REG_PCNT_BASE + 0x00b0)
+
+/* PCNT_CLK_EN : R/W ;bitpos:[16] ;default: 1'b0 ; */
+
+#define PCNT_CLK_EN  (BIT(16))
+#define PCNT_CLK_EN_M  (BIT(16))
+#define PCNT_CLK_EN_V  0x1
+#define PCNT_CLK_EN_S  16
+
+/* PCNT_CNT_PAUSE_U7 : R/W ;bitpos:[15] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit7's counter. */
+
+#define PCNT_CNT_PAUSE_U7  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_M  (BIT(15))
+#define PCNT_CNT_PAUSE_U7_V  0x1
+#define PCNT_CNT_PAUSE_U7_S  15
+
+/* PCNT_PLUS_CNT_RST_U7 : R/W ;bitpos:[14] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit7's counter. */
+
+#define PCNT_PLUS_CNT_RST_U7  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_M  (BIT(14))
+#define PCNT_PLUS_CNT_RST_U7_V  0x1
+#define PCNT_PLUS_CNT_RST_U7_S  14
+
+/* PCNT_CNT_PAUSE_U6 : R/W ;bitpos:[13] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit6's counter. */
+
+#define PCNT_CNT_PAUSE_U6  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_M  (BIT(13))
+#define PCNT_CNT_PAUSE_U6_V  0x1
+#define PCNT_CNT_PAUSE_U6_S  13
+
+/* PCNT_PLUS_CNT_RST_U6 : R/W ;bitpos:[12] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit6's counter. */
+
+#define PCNT_PLUS_CNT_RST_U6  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_M  (BIT(12))
+#define PCNT_PLUS_CNT_RST_U6_V  0x1
+#define PCNT_PLUS_CNT_RST_U6_S  12
+
+/* PCNT_CNT_PAUSE_U5 : R/W ;bitpos:[11] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit5's counter. */
+
+#define PCNT_CNT_PAUSE_U5  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_M  (BIT(11))
+#define PCNT_CNT_PAUSE_U5_V  0x1
+#define PCNT_CNT_PAUSE_U5_S  11
+
+/* PCNT_PLUS_CNT_RST_U5 : R/W ;bitpos:[10] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit5's counter. */
+
+#define PCNT_PLUS_CNT_RST_U5  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_M  (BIT(10))
+#define PCNT_PLUS_CNT_RST_U5_V  0x1
+#define PCNT_PLUS_CNT_RST_U5_S  10
+
+/* PCNT_CNT_PAUSE_U4 : R/W ;bitpos:[9] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit4's counter. */
+
+#define PCNT_CNT_PAUSE_U4  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_M  (BIT(9))
+#define PCNT_CNT_PAUSE_U4_V  0x1
+#define PCNT_CNT_PAUSE_U4_S  9
+
+/* PCNT_PLUS_CNT_RST_U4 : R/W ;bitpos:[8] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit4's counter. */
+
+#define PCNT_PLUS_CNT_RST_U4  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_M  (BIT(8))
+#define PCNT_PLUS_CNT_RST_U4_V  0x1
+#define PCNT_PLUS_CNT_RST_U4_S  8
+
+/* PCNT_CNT_PAUSE_U3 : R/W ;bitpos:[7] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit3's counter. */
+
+#define PCNT_CNT_PAUSE_U3  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_M  (BIT(7))
+#define PCNT_CNT_PAUSE_U3_V  0x1
+#define PCNT_CNT_PAUSE_U3_S  7
+
+/* PCNT_PLUS_CNT_RST_U3 : R/W ;bitpos:[6] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit3's counter. */
+
+#define PCNT_PLUS_CNT_RST_U3  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_M  (BIT(6))
+#define PCNT_PLUS_CNT_RST_U3_V  0x1
+#define PCNT_PLUS_CNT_RST_U3_S  6
+
+/* PCNT_CNT_PAUSE_U2 : R/W ;bitpos:[5] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit2's counter. */
+
+#define PCNT_CNT_PAUSE_U2  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_M  (BIT(5))
+#define PCNT_CNT_PAUSE_U2_V  0x1
+#define PCNT_CNT_PAUSE_U2_S  5
+
+/* PCNT_PLUS_CNT_RST_U2 : R/W ;bitpos:[4] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit2's counter. */
+
+#define PCNT_PLUS_CNT_RST_U2  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_M  (BIT(4))
+#define PCNT_PLUS_CNT_RST_U2_V  0x1
+#define PCNT_PLUS_CNT_RST_U2_S  4
+
+/* PCNT_CNT_PAUSE_U1 : R/W ;bitpos:[3] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit1's counter. */
+
+#define PCNT_CNT_PAUSE_U1  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_M  (BIT(3))
+#define PCNT_CNT_PAUSE_U1_V  0x1
+#define PCNT_CNT_PAUSE_U1_S  3
+
+/* PCNT_PLUS_CNT_RST_U1 : R/W ;bitpos:[2] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit1's counter. */
+
+#define PCNT_PLUS_CNT_RST_U1  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_M  (BIT(2))
+#define PCNT_PLUS_CNT_RST_U1_V  0x1
+#define PCNT_PLUS_CNT_RST_U1_S  2
+
+/* PCNT_CNT_PAUSE_U0 : R/W ;bitpos:[1] ;default: 1'b0 ; */
+
+/* Description: Set this bit to pause unit0's counter. */
+
+#define PCNT_CNT_PAUSE_U0  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_M  (BIT(1))
+#define PCNT_CNT_PAUSE_U0_V  0x1
+#define PCNT_CNT_PAUSE_U0_S  1
+
+/* PCNT_PLUS_CNT_RST_U0 : R/W ;bitpos:[0] ;default: 1'b1 ; */
+
+/* Description: Set this bit to clear unit0's counter. */
+
+#define PCNT_PLUS_CNT_RST_U0  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_M  (BIT(0))
+#define PCNT_PLUS_CNT_RST_U0_V  0x1
+#define PCNT_PLUS_CNT_RST_U0_S  0
+
+#define PCNT_DATE_REG          (DR_REG_PCNT_BASE + 0x00fc)
+
+/* PCNT_DATE : R/W ;bitpos:[31:0] ;default: 32'h14122600 ; */
+
+#define PCNT_DATE    0xFFFFFFFF
+#define PCNT_DATE_M  ((PCNT_DATE_V)<<(PCNT_DATE_S))
+#define PCNT_DATE_V  0xFFFFFFFF
+#define PCNT_DATE_S  0
+
+/* Index macros for CONF0/1/2 */
+
+#define PCNT_CONF0_U(X)   PCNT_U0_CONF0_REG + (X * 12)
+#define PCNT_CONF1_U(X)   PCNT_U0_CONF1_REG + (X * 12)
+#define PCNT_CONF2_U(X)   PCNT_U0_CONF2_REG + (X * 12)

Review Comment:
   ```suggestion
   #define PCNT_CONF0_U(X)   (PCNT_U0_CONF0_REG + (X) * 12)
   #define PCNT_CONF1_U(X)   (PCNT_U0_CONF1_REG + (X) * 12)
   #define PCNT_CONF2_U(X)   (PCNT_U0_CONF2_REG + (X) * 12)
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org