From e6f5a9ab5a8e9b1d3e131d331f760fc45528df7e Mon Sep 17 00:00:00 2001 From: Chen Jichang Date: Wed, 30 Jul 2025 14:48:22 +0800 Subject: [PATCH] feat(pcnt): support pcnt on esp32h21 --- .../test_apps/pulse_cnt/README.md | 4 +- components/hal/esp32h21/include/hal/pcnt_ll.h | 504 ++++++++++++++++++ .../esp32h21/include/soc/Kconfig.soc_caps.in | 32 ++ .../soc/esp32h21/include/soc/soc_caps.h | 14 +- components/soc/esp32h21/pcnt_periph.c | 72 +++ .../soc/esp32h21/register/soc/pcnt_struct.h | 87 +-- docs/docs_not_updated/esp32h21.txt | 1 - .../peripherals/pcnt/rotary_encoder/README.md | 4 +- 8 files changed, 633 insertions(+), 85 deletions(-) create mode 100644 components/hal/esp32h21/include/hal/pcnt_ll.h create mode 100644 components/soc/esp32h21/pcnt_periph.c diff --git a/components/esp_driver_pcnt/test_apps/pulse_cnt/README.md b/components/esp_driver_pcnt/test_apps/pulse_cnt/README.md index 7abac169b5..c0916a10f2 100644 --- a/components/esp_driver_pcnt/test_apps/pulse_cnt/README.md +++ b/components/esp_driver_pcnt/test_apps/pulse_cnt/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | diff --git a/components/hal/esp32h21/include/hal/pcnt_ll.h b/components/hal/esp32h21/include/hal/pcnt_ll.h new file mode 100644 index 0000000000..c104fbe23a --- /dev/null +++ b/components/hal/esp32h21/include/hal/pcnt_ll.h @@ -0,0 +1,504 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include "soc/pcnt_struct.h" +#include "hal/pcnt_types.h" +#include "hal/misc.h" +#include "soc/pcr_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PCNT_LL_GET_HW(num) (((num) == 0) ? (&PCNT) : NULL) +#define PCNT_LL_MAX_GLITCH_WIDTH 1023 +#define PCNT_LL_MAX_LIM SHRT_MAX +#define PCNT_LL_MIN_LIM SHRT_MIN + +typedef enum { + PCNT_LL_WATCH_EVENT_INVALID = -1, + PCNT_LL_WATCH_EVENT_THRES1, + PCNT_LL_WATCH_EVENT_THRES0, + PCNT_LL_WATCH_EVENT_LOW_LIMIT, + PCNT_LL_WATCH_EVENT_HIGH_LIMIT, + PCNT_LL_WATCH_EVENT_ZERO_CROSS, + PCNT_LL_WATCH_EVENT_MAX +} pcnt_ll_watch_event_id_t; + +typedef enum { + PCNT_LL_STEP_EVENT_REACH_INTERVAL_FORWARD = PCNT_LL_WATCH_EVENT_MAX, + PCNT_LL_STEP_EVENT_REACH_INTERVAL_BACKWARD, +} pcnt_ll_step_event_id_t; + +#define PCNT_LL_WATCH_EVENT_MASK ((1 << PCNT_LL_WATCH_EVENT_MAX) - 1) +#define PCNT_LL_UNIT_WATCH_EVENT(unit_id) (1 << (unit_id)) + +/** + * @brief Set PCNT channel edge action + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param channel PCNT channel number + * @param pos_act Counter action when detecting positive edge + * @param neg_act Counter action when detecting negative edge + */ +static inline void pcnt_ll_set_edge_action(pcnt_dev_t *hw, uint32_t unit, uint32_t channel, pcnt_channel_edge_action_t pos_act, pcnt_channel_edge_action_t neg_act) +{ + if (channel == 0) { + hw->conf_unit[unit].conf0.ch0_pos_mode_un = pos_act; + hw->conf_unit[unit].conf0.ch0_neg_mode_un = neg_act; + } else { + hw->conf_unit[unit].conf0.ch1_pos_mode_un = pos_act; + hw->conf_unit[unit].conf0.ch1_neg_mode_un = neg_act; + } +} + +/** + * @brief Set PCNT channel level action + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param channel PCNT channel number + * @param high_act Counter action when control signal is high level + * @param low_act Counter action when control signal is low level + */ +static inline void pcnt_ll_set_level_action(pcnt_dev_t *hw, uint32_t unit, uint32_t channel, pcnt_channel_level_action_t high_act, pcnt_channel_level_action_t low_act) +{ + if (channel == 0) { + hw->conf_unit[unit].conf0.ch0_hctrl_mode_un = high_act; + hw->conf_unit[unit].conf0.ch0_lctrl_mode_un = low_act; + } else { + hw->conf_unit[unit].conf0.ch1_hctrl_mode_un = high_act; + hw->conf_unit[unit].conf0.ch1_lctrl_mode_un = low_act; + } +} + +/** + * @brief Get pulse counter value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit Pulse Counter unit number + * @return PCNT count value (a signed integer) + */ +__attribute__((always_inline)) +static inline int pcnt_ll_get_count(pcnt_dev_t *hw, uint32_t unit) +{ + pcnt_un_cnt_reg_t cnt_reg; + cnt_reg.val = hw->cnt_unit[unit].val; + + int16_t value = cnt_reg.pulse_cnt_un; + return value; +} + +/** + * @brief Pause PCNT counter of PCNT unit + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + */ +__attribute__((always_inline)) +static inline void pcnt_ll_stop_count(pcnt_dev_t *hw, uint32_t unit) +{ + hw->ctrl.val |= 1 << (2 * unit + 1); +} + +/** + * @brief Resume counting for PCNT counter + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number, select from uint32_t + */ +__attribute__((always_inline)) +static inline void pcnt_ll_start_count(pcnt_dev_t *hw, uint32_t unit) +{ + hw->ctrl.val &= ~(1 << (2 * unit + 1)); +} + +/** + * @brief Clear PCNT counter value to zero + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number, select from uint32_t + */ +__attribute__((always_inline)) +static inline void pcnt_ll_clear_count(pcnt_dev_t *hw, uint32_t unit) +{ + hw->ctrl.val |= 1 << (2 * unit); + hw->ctrl.val &= ~(1 << (2 * unit)); +} + +/** + * @brief Enable PCNT step comparator event + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param enable true to enable, false to disable + */ +static inline void pcnt_ll_enable_step_notify(pcnt_dev_t *hw, uint32_t unit, bool enable) +{ + if (enable) { + hw->ctrl.val |= 1 << (8 + unit); + } else { + hw->ctrl.val &= ~(1 << (8 + unit)); + } +} + +/** + * @brief Set PCNT step value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param direction PCNT step direction + * @param value PCNT step value + */ +static inline void pcnt_ll_set_step_value(pcnt_dev_t *hw, uint32_t unit, pcnt_step_direction_t direction, uint16_t value) +{ + if (direction == PCNT_STEP_FORWARD) { + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->conf_unit[unit].conf3, cnt_h_step_un, value); + } else { + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->conf_unit[unit].conf3, cnt_l_step_un, value); + } +} + +/** + * @brief Enable PCNT interrupt for PCNT unit + * @note Each PCNT unit has five watch point events that share the same interrupt bit. + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit_mask PCNT units mask + * @param enable True to enable interrupt, False to disable interrupt + */ +static inline void pcnt_ll_enable_intr(pcnt_dev_t *hw, uint32_t unit_mask, bool enable) +{ + if (enable) { + hw->int_ena.val |= unit_mask; + } else { + hw->int_ena.val &= ~unit_mask; + } +} + +/** + * @brief Get PCNT interrupt status + * + * @param hw Peripheral PCNT hardware instance address. + * @return Interrupt status word + */ +__attribute__((always_inline)) +static inline uint32_t pcnt_ll_get_intr_status(pcnt_dev_t *hw) +{ + return hw->int_st.val; +} + +/** + * @brief Clear PCNT interrupt status + * + * @param hw Peripheral PCNT hardware instance address. + * @param status value to clear interrupt status + */ +__attribute__((always_inline)) +static inline void pcnt_ll_clear_intr_status(pcnt_dev_t *hw, uint32_t status) +{ + hw->int_clr.val = status; +} + +/** + * @brief Enable PCNT high limit event + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param enable true to enable, false to disable + */ +static inline void pcnt_ll_enable_high_limit_event(pcnt_dev_t *hw, uint32_t unit, bool enable) +{ + hw->conf_unit[unit].conf0.thr_h_lim_en_un = enable; +} + +/** + * @brief Enable PCNT low limit event + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param enable true to enable, false to disable + */ +static inline void pcnt_ll_enable_low_limit_event(pcnt_dev_t *hw, uint32_t unit, bool enable) +{ + hw->conf_unit[unit].conf0.thr_l_lim_en_un = enable; +} + +/** + * @brief Enable PCNT zero cross event + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param enable true to enable, false to disable + */ +static inline void pcnt_ll_enable_zero_cross_event(pcnt_dev_t *hw, uint32_t unit, bool enable) +{ + hw->conf_unit[unit].conf0.thr_zero_en_un = enable; +} + +/** + * @brief Enable PCNT threshold event + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param thres Threshold ID + * @param enable true to enable, false to disable + */ +static inline void pcnt_ll_enable_thres_event(pcnt_dev_t *hw, uint32_t unit, uint32_t thres, bool enable) +{ + if (thres == 0) { + hw->conf_unit[unit].conf0.thr_thres0_en_un = enable; + } else { + hw->conf_unit[unit].conf0.thr_thres1_en_un = enable; + } +} + +/** + * @brief Disable all PCNT threshold events + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit unit number + */ +static inline void pcnt_ll_disable_all_events(pcnt_dev_t *hw, uint32_t unit) +{ + hw->conf_unit[unit].conf0.val &= ~(PCNT_LL_WATCH_EVENT_MASK << 11); +} + +/** + * @brief Set PCNT high limit value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param value PCNT high limit value + */ +static inline void pcnt_ll_set_high_limit_value(pcnt_dev_t *hw, uint32_t unit, int value) +{ + pcnt_un_conf2_reg_t conf2_reg; + conf2_reg.val = hw->conf_unit[unit].conf2.val; + + conf2_reg.cnt_h_lim_un = value; + hw->conf_unit[unit].conf2.val = conf2_reg.val; +} + +/** + * @brief Set PCNT low limit value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param value PCNT low limit value + */ +static inline void pcnt_ll_set_low_limit_value(pcnt_dev_t *hw, uint32_t unit, int value) +{ + pcnt_un_conf2_reg_t conf2_reg; + conf2_reg.val = hw->conf_unit[unit].conf2.val; + + conf2_reg.cnt_l_lim_un = value; + hw->conf_unit[unit].conf2.val = conf2_reg.val; +} + +/** + * @brief Set PCNT threshold value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param thres Threshold ID + * @param value PCNT threshold value + */ +static inline void pcnt_ll_set_thres_value(pcnt_dev_t *hw, uint32_t unit, uint32_t thres, int value) +{ + pcnt_un_conf1_reg_t conf1_reg; + conf1_reg.val = hw->conf_unit[unit].conf1.val; + + if (thres == 0) { + conf1_reg.cnt_thres0_un = value; + } else { + conf1_reg.cnt_thres1_un = value; + } + hw->conf_unit[unit].conf1.val = conf1_reg.val; +} + +/** + * @brief Get PCNT high limit value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return PCNT high limit value + */ +static inline int pcnt_ll_get_high_limit_value(pcnt_dev_t *hw, uint32_t unit) +{ + pcnt_un_conf2_reg_t conf2_reg; + conf2_reg.val = hw->conf_unit[unit].conf2.val; + + int16_t value = conf2_reg.cnt_h_lim_un; + return value; +} + +/** + * @brief Get PCNT low limit value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return PCNT high limit value + */ +static inline int pcnt_ll_get_low_limit_value(pcnt_dev_t *hw, uint32_t unit) +{ + pcnt_un_conf2_reg_t conf2_reg; + conf2_reg.val = hw->conf_unit[unit].conf2.val; + + int16_t value = conf2_reg.cnt_l_lim_un ; + return value; +} + +/** + * @brief Get PCNT threshold value + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param thres Threshold ID + * @return PCNT threshold value + */ +__attribute__((always_inline)) +static inline int pcnt_ll_get_thres_value(pcnt_dev_t *hw, uint32_t unit, uint32_t thres) +{ + int16_t value; + pcnt_un_conf1_reg_t conf1_reg; + conf1_reg.val = hw->conf_unit[unit].conf1.val; + + if (thres == 0) { + value = conf1_reg.cnt_thres0_un ; + } else { + value = conf1_reg.cnt_thres1_un ; + } + return value; +} + +/** + * @brief Get PCNT unit runtime status + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return PCNT unit runtime status + */ +static inline uint32_t pcnt_ll_get_unit_status(pcnt_dev_t *hw, uint32_t unit) +{ + return hw->status_unit[unit].val; +} + +/** + * @brief Get PCNT zero cross mode + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return Zero cross mode + */ +__attribute__((always_inline)) +static inline pcnt_unit_zero_cross_mode_t pcnt_ll_get_zero_cross_mode(pcnt_dev_t *hw, uint32_t unit) +{ + return (pcnt_unit_zero_cross_mode_t)(hw->status_unit[unit].val & 0x03); +} + +/** + * @brief Get PCNT event status + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return Event status word + */ +__attribute__((always_inline)) +static inline uint32_t pcnt_ll_get_event_status(pcnt_dev_t *hw, uint32_t unit) +{ + return hw->status_unit[unit].val >> 2; +} + +/** + * @brief Set PCNT glitch filter threshold + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param filter_val PCNT signal filter value, counter in APB_CLK cycles. + * Any pulses lasting shorter than this will be ignored when the filter is enabled. + */ +static inline void pcnt_ll_set_glitch_filter_thres(pcnt_dev_t *hw, uint32_t unit, uint32_t filter_val) +{ + hw->conf_unit[unit].conf0.filter_thres_un = filter_val; +} + +/** + * @brief Get PCNT glitch filter threshold + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @return glitch filter threshold + */ +static inline uint32_t pcnt_ll_get_glitch_filter_thres(pcnt_dev_t *hw, uint32_t unit) +{ + return hw->conf_unit[unit].conf0.filter_thres_un; +} + +/** + * @brief Enable PCNT glitch filter + * + * @param hw Peripheral PCNT hardware instance address. + * @param unit PCNT unit number + * @param enable True to enable the filter, False to disable the filter + */ +static inline void pcnt_ll_enable_glitch_filter(pcnt_dev_t *hw, uint32_t unit, bool enable) +{ + hw->conf_unit[unit].conf0.filter_en_un = enable; +} + +/** + * @brief Get interrupt status register address. + * + * @param hw Beginning address of the peripheral registers. + * + * @return Interrupt status register address + */ +static inline volatile void *pcnt_ll_get_intr_status_reg(pcnt_dev_t *hw) +{ + return &hw->int_st.val; +} + +/** + * @brief Enable or disable the bus clock for the PCNT module + * + * @param set_bit True to set bit, false to clear bit + */ +static inline void pcnt_ll_enable_bus_clock(int group_id, bool enable) +{ + (void)group_id; + PCR.pcnt_conf.pcnt_clk_en = enable; +} + +/** + * @brief Reset the PCNT module + */ +static inline void pcnt_ll_reset_register(int group_id) +{ + (void)group_id; + PCR.pcnt_conf.pcnt_rst_en = 1; + PCR.pcnt_conf.pcnt_rst_en = 0; +} + +/** + * @brief Check if the step notify is supported + */ +static inline bool pcnt_ll_is_step_notify_supported(int group_id) +{ + (void)group_id; + return true; +} + + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in index 2c7520c1be..191165ce27 100644 --- a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in @@ -115,6 +115,10 @@ config SOC_REG_I2C_SUPPORTED bool default y +config SOC_PCNT_SUPPORTED + bool + default y + config SOC_TWAI_SUPPORTED bool default y @@ -467,6 +471,34 @@ config SOC_LEDC_CHANNEL_NUM int default 6 +config SOC_PCNT_GROUPS + int + default 1 + +config SOC_PCNT_UNITS_PER_GROUP + int + default 4 + +config SOC_PCNT_CHANNELS_PER_UNIT + int + default 2 + +config SOC_PCNT_THRES_POINT_PER_UNIT + int + default 2 + +config SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE + bool + default y + +config SOC_PCNT_SUPPORT_CLEAR_SIGNAL + bool + default y + +config SOC_PCNT_SUPPORT_STEP_NOTIFY + bool + default y + config SOC_RMT_GROUPS int default 1 diff --git a/components/soc/esp32h21/include/soc/soc_caps.h b/components/soc/esp32h21/include/soc/soc_caps.h index 007d767c0e..5ad8faaa89 100644 --- a/components/soc/esp32h21/include/soc/soc_caps.h +++ b/components/soc/esp32h21/include/soc/soc_caps.h @@ -72,7 +72,7 @@ #define SOC_MODEM_CLOCK_SUPPORTED 1 #define SOC_REG_I2C_SUPPORTED 1 // #define SOC_PHY_SUPPORTED 1 -// #define SOC_PCNT_SUPPORTED 1 //TODO: [ESP32H21] IDF-11566 +#define SOC_PCNT_SUPPORTED 1 // #define SOC_MCPWM_SUPPORTED 1 //TODO: [ESP32H21] IDF-11601 #define SOC_TWAI_SUPPORTED 1 // #define SOC_ETM_SUPPORTED 1 //TODO: [ESP32H21] IDF-11576 @@ -303,11 +303,13 @@ // #define SOC_MPU_REGION_WO_SUPPORTED 0 /*-------------------------- PCNT CAPS ---------------------------------------*/ -// #define SOC_PCNT_GROUPS 1U -// #define SOC_PCNT_UNITS_PER_GROUP 4 -// #define SOC_PCNT_CHANNELS_PER_UNIT 2 -// #define SOC_PCNT_THRES_POINT_PER_UNIT 2 -// #define SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE 1 +#define SOC_PCNT_GROUPS 1U +#define SOC_PCNT_UNITS_PER_GROUP 4 +#define SOC_PCNT_CHANNELS_PER_UNIT 2 +#define SOC_PCNT_THRES_POINT_PER_UNIT 2 +#define SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE 1 +#define SOC_PCNT_SUPPORT_CLEAR_SIGNAL 1 +#define SOC_PCNT_SUPPORT_STEP_NOTIFY 1 /*--------------------------- RMT CAPS ---------------------------------------*/ #define SOC_RMT_GROUPS 1U /*!< One RMT group */ diff --git a/components/soc/esp32h21/pcnt_periph.c b/components/soc/esp32h21/pcnt_periph.c new file mode 100644 index 0000000000..8d1ddfc062 --- /dev/null +++ b/components/soc/esp32h21/pcnt_periph.c @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/pcnt_periph.h" +#include "soc/gpio_sig_map.h" +#include "soc/pcnt_reg.h" + +const pcnt_signal_conn_t pcnt_periph_signals = { + .groups = { + [0] = { + .irq = ETS_PCNT_INTR_SOURCE, + .module_name = "pcnt0", + .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 + } + }, + .clear_sig = PCNT_RST_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 + } + }, + .clear_sig = PCNT_RST_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 + } + }, + .clear_sig = PCNT_RST_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 + } + }, + .clear_sig = PCNT_RST_IN3_IDX + } + } + } + } +}; diff --git a/components/soc/esp32h21/register/soc/pcnt_struct.h b/components/soc/esp32h21/register/soc/pcnt_struct.h index 83e2b656b7..e79d035663 100644 --- a/components/soc/esp32h21/register/soc/pcnt_struct.h +++ b/components/soc/esp32h21/register/soc/pcnt_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -156,65 +156,14 @@ typedef union { /** cnt_h_step_u0 : R/W; bitpos: [15:0]; default: 0; * Configures the forward rotation step value for unit 0. */ - uint32_t cnt_h_step_u0:16; + uint32_t cnt_h_step_un:16; /** cnt_l_step_u0 : R/W; bitpos: [31:16]; default: 0; * Configures the reverse rotation step value for unit 0. */ - uint32_t cnt_l_step_u0:16; + uint32_t cnt_l_step_un:16; }; uint32_t val; -} pcnt_u0_conf3_reg_t; - -/** Type of u1_conf3 register - * Configuration register for unit $n's step value. - */ -typedef union { - struct { - /** cnt_h_step_u1 : R/W; bitpos: [15:0]; default: 0; - * Configures the forward rotation step value for unit 1. - */ - uint32_t cnt_h_step_u1:16; - /** cnt_l_step_u1 : R/W; bitpos: [31:16]; default: 0; - * Configures the reverse rotation step value for unit 1. - */ - uint32_t cnt_l_step_u1:16; - }; - uint32_t val; -} pcnt_u1_conf3_reg_t; - -/** Type of u2_conf3 register - * Configuration register for unit $n's step value. - */ -typedef union { - struct { - /** cnt_h_step_u2 : R/W; bitpos: [15:0]; default: 0; - * Configures the forward rotation step value for unit 2. - */ - uint32_t cnt_h_step_u2:16; - /** cnt_l_step_u2 : R/W; bitpos: [31:16]; default: 0; - * Configures the reverse rotation step value for unit 2. - */ - uint32_t cnt_l_step_u2:16; - }; - uint32_t val; -} pcnt_u2_conf3_reg_t; - -/** Type of u3_conf3 register - * Configuration register for unit $n's step value. - */ -typedef union { - struct { - /** cnt_h_step_u3 : R/W; bitpos: [15:0]; default: 0; - * Configures the forward rotation step value for unit 3. - */ - uint32_t cnt_h_step_u3:16; - /** cnt_l_step_u3 : R/W; bitpos: [31:16]; default: 0; - * Configures the reverse rotation step value for unit 3. - */ - uint32_t cnt_l_step_u3:16; - }; - uint32_t val; -} pcnt_u3_conf3_reg_t; +} pcnt_un_conf3_reg_t; /** Type of ctrl register * Control register for all counters @@ -484,29 +433,19 @@ typedef union { } pcnt_date_reg_t; -typedef struct { - volatile pcnt_un_conf0_reg_t u0_conf0; - volatile pcnt_un_conf1_reg_t u0_conf1; - volatile pcnt_un_conf2_reg_t u0_conf2; - volatile pcnt_u0_conf3_reg_t u0_conf3; - volatile pcnt_un_conf0_reg_t u1_conf0; - volatile pcnt_un_conf1_reg_t u1_conf1; - volatile pcnt_un_conf2_reg_t u1_conf2; - volatile pcnt_u1_conf3_reg_t u1_conf3; - volatile pcnt_un_conf0_reg_t u2_conf0; - volatile pcnt_un_conf1_reg_t u2_conf1; - volatile pcnt_un_conf2_reg_t u2_conf2; - volatile pcnt_u2_conf3_reg_t u2_conf3; - volatile pcnt_un_conf0_reg_t u3_conf0; - volatile pcnt_un_conf1_reg_t u3_conf1; - volatile pcnt_un_conf2_reg_t u3_conf2; - volatile pcnt_u3_conf3_reg_t u3_conf3; - volatile pcnt_un_cnt_reg_t un_cnt[4]; +typedef struct pcnt_dev_t { + volatile struct { + pcnt_un_conf0_reg_t conf0; + pcnt_un_conf1_reg_t conf1; + pcnt_un_conf2_reg_t conf2; + pcnt_un_conf3_reg_t conf3; + } conf_unit[4]; + volatile pcnt_un_cnt_reg_t cnt_unit[4]; volatile pcnt_int_raw_reg_t int_raw; volatile pcnt_int_st_reg_t int_st; volatile pcnt_int_ena_reg_t int_ena; volatile pcnt_int_clr_reg_t int_clr; - volatile pcnt_un_status_reg_t un_status[4]; + volatile pcnt_un_status_reg_t status_unit[4]; volatile pcnt_ctrl_reg_t ctrl; uint32_t reserved_074[34]; volatile pcnt_date_reg_t date; diff --git a/docs/docs_not_updated/esp32h21.txt b/docs/docs_not_updated/esp32h21.txt index 097084c644..19ee3537b6 100644 --- a/docs/docs_not_updated/esp32h21.txt +++ b/docs/docs_not_updated/esp32h21.txt @@ -177,7 +177,6 @@ api-reference/peripherals/lcd/i2c_lcd.rst api-reference/peripherals/lcd/spi_lcd.rst api-reference/peripherals/lcd/rgb_lcd.rst api-reference/peripherals/lcd/parl_lcd.rst -api-reference/peripherals/pcnt.rst api-reference/peripherals/spi_features.rst api-reference/peripherals/ppa.rst api-reference/peripherals/ledc.rst diff --git a/examples/peripherals/pcnt/rotary_encoder/README.md b/examples/peripherals/pcnt/rotary_encoder/README.md index f38ea2dc13..fe0f5079d0 100644 --- a/examples/peripherals/pcnt/rotary_encoder/README.md +++ b/examples/peripherals/pcnt/rotary_encoder/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | # Rotary Encoder Example