Ver Fonte

pcnt: add pcnt peripheral signal connections

pcnt: fix bug in clear interrupt status
morris há 5 anos atrás
pai
commit
74d78148bc

+ 13 - 22
components/driver/pcnt.c

@@ -1,4 +1,4 @@
-// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
+// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,13 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "soc/soc_caps.h"
 #include "freertos/FreeRTOS.h"
 #include "freertos/semphr.h"
-#include "freertos/xtensa_api.h"
 #include "esp_log.h"
-#include "driver/pcnt.h"
+#include "soc/soc_caps.h"
+#if SOC_PCNT_SUPPORTED
 #include "driver/periph_ctrl.h"
+#include "driver/pcnt.h"
 #include "hal/pcnt_hal.h"
 #include "esp_rom_gpio.h"
 
@@ -85,28 +85,18 @@ static inline esp_err_t _pcnt_set_pin(pcnt_port_t pcnt_port, pcnt_unit_t unit, p
     PCNT_CHECK(GPIO_IS_VALID_GPIO(pulse_io) || pulse_io < 0, PCNT_GPIO_ERR_STR, ESP_ERR_INVALID_ARG);
     PCNT_CHECK(GPIO_IS_VALID_GPIO(ctrl_io) || ctrl_io < 0, PCNT_GPIO_ERR_STR, ESP_ERR_INVALID_ARG);
 
-    int sig_base  = (channel == 0) ? PCNT_SIG_CH0_IN0_IDX  : PCNT_SIG_CH1_IN0_IDX;
-    int ctrl_base = (channel == 0) ? PCNT_CTRL_CH0_IN0_IDX : PCNT_CTRL_CH1_IN0_IDX;
-    if (unit > 4) {
-        sig_base  += 12; // GPIO matrix assignments have a gap between units 4 & 5
-        ctrl_base += 12;
-    }
-
-    int input_sig_index = sig_base  + (4 * unit);
-    int ctrl_sig_index  = ctrl_base + (4 * unit);
-
     if (pulse_io >= 0) {
         PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pulse_io], PIN_FUNC_GPIO);
         gpio_set_direction(pulse_io, GPIO_MODE_INPUT);
         gpio_set_pull_mode(pulse_io, GPIO_PULLUP_ONLY);
-        esp_rom_gpio_connect_in_signal(pulse_io, input_sig_index, 0);
+        esp_rom_gpio_connect_in_signal(pulse_io, pcnt_periph_signals.units[unit].channels[channel].pulse_sig, 0);
     }
 
     if (ctrl_io >= 0) {
         PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[ctrl_io], PIN_FUNC_GPIO);
         gpio_set_direction(ctrl_io, GPIO_MODE_INPUT);
         gpio_set_pull_mode(ctrl_io, GPIO_PULLUP_ONLY);
-        esp_rom_gpio_connect_in_signal(ctrl_io, ctrl_sig_index, 0);
+        esp_rom_gpio_connect_in_signal(ctrl_io, pcnt_periph_signals.units[unit].channels[channel].control_sig, 0);
     }
 
     return ESP_OK;
@@ -284,11 +274,11 @@ static inline esp_err_t _pcnt_isr_handler_remove(pcnt_port_t pcnt_port, pcnt_uni
 // pcnt interrupt service
 static void IRAM_ATTR pcnt_intr_service(void *arg)
 {
-    uint32_t status, mask = 0;
+    uint32_t status = 0;
     pcnt_port_t pcnt_port = (pcnt_port_t)arg;
     pcnt_hal_get_intr_status(&(p_pcnt_obj[pcnt_port]->hal), &status);
+    pcnt_hal_clear_intr_status(&(p_pcnt_obj[pcnt_port]->hal), status);
     
-    mask = status;
     while (status) {
         int unit = __builtin_ffs(status) - 1;
         status &= ~(1 << unit);
@@ -297,7 +287,6 @@ static void IRAM_ATTR pcnt_intr_service(void *arg)
             (pcnt_isr_func[unit].fn)(pcnt_isr_func[unit].args);
         }
     }
-    pcnt_hal_clear_intr_status(&(p_pcnt_obj[pcnt_port]->hal), mask);
 }
 
 static inline esp_err_t _pcnt_isr_service_install(pcnt_port_t pcnt_port, int intr_alloc_flags)
@@ -351,10 +340,10 @@ static inline esp_err_t _pcnt_unit_config(pcnt_port_t pcnt_port, const pcnt_conf
     /*Enalbe hardware module*/
     static bool pcnt_enable = false;
     if (pcnt_enable == false) {
-        periph_module_reset(PERIPH_PCNT_MODULE);
+        periph_module_reset(pcnt_periph_signals.module);
         pcnt_enable = true;
     }
-    periph_module_enable(PERIPH_PCNT_MODULE);
+    periph_module_enable(pcnt_periph_signals.module);
     /*Set counter range*/
     _pcnt_set_event_value(pcnt_port, unit, PCNT_EVT_H_LIM, pcnt_config->counter_h_lim);
     _pcnt_set_event_value(pcnt_port, unit, PCNT_EVT_L_LIM, pcnt_config->counter_l_lim);
@@ -504,7 +493,7 @@ esp_err_t pcnt_isr_register(void (*fun)(void *), void *arg, int intr_alloc_flags
     esp_err_t ret = ESP_FAIL;
     PCNT_CHECK(fun != NULL, PCNT_ADDRESS_ERR_STR, ESP_ERR_INVALID_ARG);
     PCNT_ENTER_CRITICAL(&pcnt_spinlock);
-    ret = esp_intr_alloc(ETS_PCNT_INTR_SOURCE, intr_alloc_flags, fun, arg, handle);
+    ret = esp_intr_alloc(pcnt_periph_signals.irq, intr_alloc_flags, fun, arg, handle);
     PCNT_EXIT_CRITICAL(&pcnt_spinlock);
     return ret;
 }
@@ -529,3 +518,5 @@ void pcnt_isr_service_uninstall()
 {
     _pcnt_isr_service_uninstall(PCNT_PORT_0);
 }
+
+#endif // #if SOC_PCNT_SUPPORTED

+ 51 - 6
components/hal/esp32/include/hal/pcnt_ll.h

@@ -33,33 +33,66 @@ extern "C" {
 #define PCNT_LL_GET_HW(num) (((num) == 0) ? (&PCNT) : NULL)
 
 /**
- * @brief Set PCNT counter mode
+ * @brief Set PCNT channel edge mode
  *
  * @param hw Peripheral PCNT hardware instance address.
  * @param unit PCNT unit number
  * @param channel PCNT channel number
  * @param pos_mode Counter mode when detecting positive edge
  * @param neg_mode Counter mode when detecting negative edge
- * @param hctrl_mode Counter mode when control signal is high level
- * @param lctrl_mode Counter mode when control signal is low level
  */
-static inline void pcnt_ll_set_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode)
+static inline void pcnt_ll_set_edge_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode)
 {
     typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0;
     if (channel == 0) {
         conf0_reg.ch0_pos_mode = pos_mode;
         conf0_reg.ch0_neg_mode = neg_mode;
-        conf0_reg.ch0_hctrl_mode = hctrl_mode;
-        conf0_reg.ch0_lctrl_mode = lctrl_mode;
     } else {
         conf0_reg.ch1_pos_mode = pos_mode;
         conf0_reg.ch1_neg_mode = neg_mode;
+    }
+    hw->conf_unit[unit].conf0 = conf0_reg;
+}
+
+/**
+ * @brief Set PCNT channel level mode
+ *
+ * @param hw Peripheral PCNT hardware instance address.
+ * @param unit PCNT unit number
+ * @param channel PCNT channel number
+ * @param hctrl_mode Counter mode when control signal is high level
+ * @param lctrl_mode Counter mode when control signal is low level
+ */
+static inline void pcnt_ll_set_level_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode)
+{
+    typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0;
+    if (channel == 0) {
+        conf0_reg.ch0_hctrl_mode = hctrl_mode;
+        conf0_reg.ch0_lctrl_mode = lctrl_mode;
+    } else {
         conf0_reg.ch1_hctrl_mode = hctrl_mode;
         conf0_reg.ch1_lctrl_mode = lctrl_mode;
     }
     hw->conf_unit[unit].conf0 = conf0_reg;
 }
 
+/**
+ * @brief Set PCNT counter mode
+ *
+ * @param hw Peripheral PCNT hardware instance address.
+ * @param unit PCNT unit number
+ * @param channel PCNT channel number
+ * @param pos_mode Counter mode when detecting positive edge
+ * @param neg_mode Counter mode when detecting negative edge
+ * @param hctrl_mode Counter mode when control signal is high level
+ * @param lctrl_mode Counter mode when control signal is low level
+ */
+static inline void pcnt_ll_set_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode)
+{
+    pcnt_ll_set_edge_mode(hw, unit, channel, pos_mode, neg_mode);
+    pcnt_ll_set_level_mode(hw, unit, channel, hctrl_mode, lctrl_mode);
+}
+
 /**
  * @brief Get pulse counter value
  *
@@ -247,6 +280,18 @@ static inline void pcnt_ll_get_event_value(pcnt_dev_t *hw, pcnt_unit_t unit, pcn
     }
 }
 
+/**
+ * @brief Get PCNT event status
+ *
+ * @param hw Peripheral PCNT hardware instance address.
+ * @param unit PCNT unit number
+ * @return event status word
+ */
+static inline uint32_t pcnt_ll_get_event_status(pcnt_dev_t *hw, pcnt_unit_t unit)
+{
+    return hw->status_unit[unit].val;
+}
+
 /**
  * @brief Set PCNT filter value
  *

+ 51 - 6
components/hal/esp32s2/include/hal/pcnt_ll.h

@@ -33,33 +33,66 @@ extern "C" {
 #define PCNT_LL_GET_HW(num) (((num) == 0) ? (&PCNT) : NULL)
 
 /**
- * @brief Set PCNT counter mode
+ * @brief Set PCNT channel edge mode
  *
  * @param hw Peripheral PCNT hardware instance address.
  * @param unit PCNT unit number
  * @param channel PCNT channel number
  * @param pos_mode Counter mode when detecting positive edge
  * @param neg_mode Counter mode when detecting negative edge
- * @param hctrl_mode Counter mode when control signal is high level
- * @param lctrl_mode Counter mode when control signal is low level
  */
-static inline void pcnt_ll_set_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode)
+static inline void pcnt_ll_set_edge_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode)
 {
     typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0;
     if (channel == 0) {
         conf0_reg.ch0_pos_mode = pos_mode;
         conf0_reg.ch0_neg_mode = neg_mode;
-        conf0_reg.ch0_hctrl_mode = hctrl_mode;
-        conf0_reg.ch0_lctrl_mode = lctrl_mode;
     } else {
         conf0_reg.ch1_pos_mode = pos_mode;
         conf0_reg.ch1_neg_mode = neg_mode;
+    }
+    hw->conf_unit[unit].conf0 = conf0_reg;
+}
+
+/**
+ * @brief Set PCNT channel level mode
+ *
+ * @param hw Peripheral PCNT hardware instance address.
+ * @param unit PCNT unit number
+ * @param channel PCNT channel number
+ * @param hctrl_mode Counter mode when control signal is high level
+ * @param lctrl_mode Counter mode when control signal is low level
+ */
+static inline void pcnt_ll_set_level_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode)
+{
+    typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0;
+    if (channel == 0) {
+        conf0_reg.ch0_hctrl_mode = hctrl_mode;
+        conf0_reg.ch0_lctrl_mode = lctrl_mode;
+    } else {
         conf0_reg.ch1_hctrl_mode = hctrl_mode;
         conf0_reg.ch1_lctrl_mode = lctrl_mode;
     }
     hw->conf_unit[unit].conf0 = conf0_reg;
 }
 
+/**
+ * @brief Set PCNT counter mode
+ *
+ * @param hw Peripheral PCNT hardware instance address.
+ * @param unit PCNT unit number
+ * @param channel PCNT channel number
+ * @param pos_mode Counter mode when detecting positive edge
+ * @param neg_mode Counter mode when detecting negative edge
+ * @param hctrl_mode Counter mode when control signal is high level
+ * @param lctrl_mode Counter mode when control signal is low level
+ */
+static inline void pcnt_ll_set_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode)
+{
+    pcnt_ll_set_edge_mode(hw, unit, channel, pos_mode, neg_mode);
+    pcnt_ll_set_level_mode(hw, unit, channel, hctrl_mode, lctrl_mode);
+}
+
 /**
  * @brief Get pulse counter value
  *
@@ -247,6 +280,18 @@ static inline void pcnt_ll_get_event_value(pcnt_dev_t *hw, pcnt_unit_t unit, pcn
     }
 }
 
+/**
+ * @brief Get PCNT event status
+ *
+ * @param hw Peripheral PCNT hardware instance address.
+ * @param unit PCNT unit number
+ * @return event status word
+ */
+static inline uint32_t pcnt_ll_get_event_status(pcnt_dev_t *hw, pcnt_unit_t unit)
+{
+    return hw->status_unit[unit].val;
+}
+
 /**
  * @brief Set PCNT filter value
  *

+ 51 - 6
components/hal/esp32s3/include/hal/pcnt_ll.h

@@ -33,33 +33,66 @@ extern "C" {
 #define PCNT_LL_GET_HW(num) (((num) == 0) ? (&PCNT) : NULL)
 
 /**
- * @brief Set PCNT counter mode
+ * @brief Set PCNT channel edge mode
  *
  * @param hw Peripheral PCNT hardware instance address.
  * @param unit PCNT unit number
  * @param channel PCNT channel number
  * @param pos_mode Counter mode when detecting positive edge
  * @param neg_mode Counter mode when detecting negative edge
- * @param hctrl_mode Counter mode when control signal is high level
- * @param lctrl_mode Counter mode when control signal is low level
  */
-static inline void pcnt_ll_set_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode)
+static inline void pcnt_ll_set_edge_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode)
 {
     typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0;
     if (channel == 0) {
         conf0_reg.ch0_pos_mode = pos_mode;
         conf0_reg.ch0_neg_mode = neg_mode;
-        conf0_reg.ch0_hctrl_mode = hctrl_mode;
-        conf0_reg.ch0_lctrl_mode = lctrl_mode;
     } else {
         conf0_reg.ch1_pos_mode = pos_mode;
         conf0_reg.ch1_neg_mode = neg_mode;
+    }
+    hw->conf_unit[unit].conf0 = conf0_reg;
+}
+
+/**
+ * @brief Set PCNT channel level mode
+ *
+ * @param hw Peripheral PCNT hardware instance address.
+ * @param unit PCNT unit number
+ * @param channel PCNT channel number
+ * @param hctrl_mode Counter mode when control signal is high level
+ * @param lctrl_mode Counter mode when control signal is low level
+ */
+static inline void pcnt_ll_set_level_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode)
+{
+    typeof(hw->conf_unit[unit].conf0) conf0_reg = hw->conf_unit[unit].conf0;
+    if (channel == 0) {
+        conf0_reg.ch0_hctrl_mode = hctrl_mode;
+        conf0_reg.ch0_lctrl_mode = lctrl_mode;
+    } else {
         conf0_reg.ch1_hctrl_mode = hctrl_mode;
         conf0_reg.ch1_lctrl_mode = lctrl_mode;
     }
     hw->conf_unit[unit].conf0 = conf0_reg;
 }
 
+/**
+ * @brief Set PCNT counter mode
+ *
+ * @param hw Peripheral PCNT hardware instance address.
+ * @param unit PCNT unit number
+ * @param channel PCNT channel number
+ * @param pos_mode Counter mode when detecting positive edge
+ * @param neg_mode Counter mode when detecting negative edge
+ * @param hctrl_mode Counter mode when control signal is high level
+ * @param lctrl_mode Counter mode when control signal is low level
+ */
+static inline void pcnt_ll_set_mode(pcnt_dev_t *hw, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode)
+{
+    pcnt_ll_set_edge_mode(hw, unit, channel, pos_mode, neg_mode);
+    pcnt_ll_set_level_mode(hw, unit, channel, hctrl_mode, lctrl_mode);
+}
+
 /**
  * @brief Get pulse counter value
  *
@@ -247,6 +280,18 @@ static inline void pcnt_ll_get_event_value(pcnt_dev_t *hw, pcnt_unit_t unit, pcn
     }
 }
 
+/**
+ * @brief Get PCNT event status
+ *
+ * @param hw Peripheral PCNT hardware instance address.
+ * @param unit PCNT unit number
+ * @return event status word
+ */
+static inline uint32_t pcnt_ll_get_event_status(pcnt_dev_t *hw, pcnt_unit_t unit)
+{
+    return hw->status_unit[unit].val;
+}
+
 /**
  * @brief Set PCNT filter value
  *

+ 1 - 0
components/soc/soc/esp32/CMakeLists.txt

@@ -2,6 +2,7 @@ add_library(soc_esp32 STATIC
     "adc_periph.c"
     "dac_periph.c"
     "gpio_periph.c"
+    "pcnt_periph.c"
     "rtc_io_periph.c"
     "rtc_periph.c"
     "sdio_slave_periph.c"

+ 2 - 0
components/soc/soc/esp32/include/soc/soc_caps.h

@@ -63,6 +63,7 @@
 #define SOC_MCPWM_SUPPORTED         1
 #define SOC_SDMMC_HOST_SUPPORTED    1
 #define SOC_BT_SUPPORTED            1
+#define SOC_PCNT_SUPPORTED          1
 #define SOC_SDIO_SLAVE_SUPPORTED    1
 #define SOC_TWAI_SUPPORTED          1
 #define SOC_EMAC_SUPPORTED          1
@@ -155,6 +156,7 @@
 // ESP32 have 1 PCNT peripheral
 #define SOC_PCNT_PORT_NUM      (1)
 #define SOC_PCNT_UNIT_NUM      (8)
+#define SOC_PCNT_UNIT_CHANNEL_NUM (2)
 
 /*-------------------------- RMT CAPS ----------------------------------------*/
 #define SOC_RMT_CHANNEL_MEM_WORDS   (64) /*!< Each channel owns 64 words memory */

+ 119 - 0
components/soc/soc/esp32/pcnt_periph.c

@@ -0,0 +1,119 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed 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.
+
+#include "soc/pcnt_periph.h"
+#include "soc/gpio_sig_map.h"
+
+const pcnt_signal_conn_t pcnt_periph_signals = {
+    .module = PERIPH_PCNT_MODULE,
+    .irq = ETS_PCNT_INTR_SOURCE,
+    .units = {
+        [0] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN0_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN0_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN0_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN0_IDX
+                }
+            }
+        },
+        [1] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN1_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN1_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN1_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN1_IDX
+                }
+            }
+        },
+        [2] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN2_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN2_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN2_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN2_IDX
+                }
+            }
+        },
+        [3] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN3_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN3_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN3_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN3_IDX
+                }
+            }
+        },
+        [4] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN4_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN4_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN4_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN4_IDX
+                }
+            }
+        },
+        [5] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN5_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN5_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN5_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN5_IDX
+                }
+            }
+        },
+        [6] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN6_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN6_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN6_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN6_IDX
+                }
+            }
+        },
+        [7] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN7_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN7_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN7_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN7_IDX
+                }
+            }
+        }
+    }
+};

+ 1 - 0
components/soc/soc/esp32s2/CMakeLists.txt

@@ -2,6 +2,7 @@ add_library(soc_esp32s2 STATIC
     "adc_periph.c"
     "dac_periph.c"
     "gpio_periph.c"
+    "pcnt_periph.c"
     "rtc_io_periph.c"
     "rtc_periph.c"
     "interrupts.c"

+ 2 - 0
components/soc/soc/esp32s2/include/soc/soc_caps.h

@@ -43,6 +43,7 @@
 #define SOC_SUPPORTS_SECURE_DL_MODE 1
 #define SOC_RISCV_COPROC_SUPPORTED 1
 #define SOC_USB_SUPPORTED 1
+#define SOC_PCNT_SUPPORTED 1
 
 #define SOC_CACHE_SUPPORT_WRAP    1
 
@@ -132,6 +133,7 @@
 // ESP32-S2 have 1 PCNT peripheral
 #define SOC_PCNT_PORT_NUM      (1)
 #define SOC_PCNT_UNIT_NUM      (4) // ESP32-S2 only have 4 unit
+#define SOC_PCNT_UNIT_CHANNEL_NUM (2)
 
 /*-------------------------- RMT CAPS ----------------------------------------*/
 #define SOC_RMT_CHANNEL_MEM_WORDS (64)       /*!< Each channel owns 64 words memory (1 word = 4 Bytes) */

+ 71 - 0
components/soc/soc/esp32s2/pcnt_periph.c

@@ -0,0 +1,71 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed 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.
+
+#include "soc/pcnt_periph.h"
+#include "soc/gpio_sig_map.h"
+
+const pcnt_signal_conn_t pcnt_periph_signals = {
+    .module = PERIPH_PCNT_MODULE,
+    .irq = ETS_PCNT_INTR_SOURCE,
+    .units = {
+        [0] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN0_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN0_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN0_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN0_IDX
+                }
+            }
+        },
+        [1] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN1_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN1_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN1_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN1_IDX
+                }
+            }
+        },
+        [2] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN2_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN2_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN2_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN2_IDX
+                }
+            }
+        },
+        [3] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN3_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN3_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN3_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN3_IDX
+                }
+            }
+        }
+    }
+};

+ 1 - 0
components/soc/soc/esp32s3/CMakeLists.txt

@@ -6,6 +6,7 @@ add_library(soc_esp32s3 STATIC
     "i2s_periph.c"
     "interrupts.c"
     "ledc_periph.c"
+    "pcnt_periph.c"
     "rtc_io_periph.c"
     "rtc_periph.c"
     "sdio_slave_periph.c"

+ 0 - 26
components/soc/soc/esp32s3/include/soc/pcnt_caps.h

@@ -1,26 +0,0 @@
-// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed 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.
-
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define SOC_PCNT_PORT_NUM      (1)
-#define SOC_PCNT_UNIT_NUM      (4)
-
-#ifdef __cplusplus
-}
-#endif

+ 4 - 1
components/soc/soc/esp32s3/include/soc/soc_caps.h

@@ -6,6 +6,7 @@
 #pragma once
 
 /*-------------------------- COMMON CAPS ---------------------------------------*/
+#define SOC_PCNT_SUPPORTED 1
 #define SOC_TWAI_SUPPORTED 1
 #define SOC_GDMA_SUPPORTED 1
 #define SOC_CPU_CORES_NUM 2
@@ -42,7 +43,9 @@
 #include "mpu_caps.h"
 
 /*-------------------------- PCNT CAPS ---------------------------------------*/
-#include "pcnt_caps.h"
+#define SOC_PCNT_PORT_NUM         (1)
+#define SOC_PCNT_UNIT_NUM         (4)
+#define SOC_PCNT_UNIT_CHANNEL_NUM (2)
 
 /*-------------------------- RMT CAPS ----------------------------------------*/
 #include "rmt_caps.h"

+ 71 - 0
components/soc/soc/esp32s3/pcnt_periph.c

@@ -0,0 +1,71 @@
+// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed 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.
+
+#include "soc/pcnt_periph.h"
+#include "soc/gpio_sig_map.h"
+
+const pcnt_signal_conn_t pcnt_periph_signals = {
+    .module = PERIPH_PCNT_MODULE,
+    .irq = ETS_PCNT_INTR_SOURCE,
+    .units = {
+        [0] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN0_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN0_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN0_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN0_IDX
+                }
+            }
+        },
+        [1] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN1_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN1_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN1_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN1_IDX
+                }
+            }
+        },
+        [2] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN2_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN2_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN2_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN2_IDX
+                }
+            }
+        },
+        [3] = {
+            .channels = {
+                [0] = {
+                    .control_sig = PCNT_CTRL_CH0_IN3_IDX,
+                    .pulse_sig = PCNT_SIG_CH0_IN3_IDX
+                },
+                [1] = {
+                    .control_sig = PCNT_CTRL_CH1_IN3_IDX,
+                    .pulse_sig = PCNT_SIG_CH1_IN3_IDX
+                }
+            }
+        }
+    }
+};

+ 25 - 0
components/soc/soc/include/soc/pcnt_periph.h

@@ -13,5 +13,30 @@
 // limitations under the License.
 
 #pragma once
+
+#include <stdint.h>
+#include "soc/soc_caps.h"
+#include "soc/periph_defs.h"
 #include "soc/pcnt_reg.h"
 #include "soc/pcnt_struct.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    struct {
+        struct {
+            const uint32_t pulse_sig;
+            const uint32_t control_sig;
+        } channels[SOC_PCNT_UNIT_CHANNEL_NUM];
+    } units[SOC_PCNT_UNIT_NUM];
+    const uint32_t irq;
+    const periph_module_t module;
+} pcnt_signal_conn_t;
+
+extern const pcnt_signal_conn_t pcnt_periph_signals;
+
+#ifdef __cplusplus
+}
+#endif