feat(pcnt): support step_notify on esp32h2 eco5

This commit is contained in:
Chen Jichang 2024-12-09 19:05:04 +08:00
parent a0a85db5f5
commit 3779757cd3
7 changed files with 260 additions and 136 deletions

View File

@ -667,8 +667,10 @@ esp_err_t pcnt_unit_remove_watch_point(pcnt_unit_handle_t unit, int watch_point)
#if SOC_PCNT_SUPPORT_STEP_NOTIFY
esp_err_t pcnt_unit_add_watch_step(pcnt_unit_handle_t unit, int step_interval)
{
pcnt_group_t *group = NULL;
pcnt_group_t *group = unit->group;
if (!pcnt_ll_is_step_notify_supported(group->group_id)) {
ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "watch step is not supported by this chip revision");
}
ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
ESP_RETURN_ON_FALSE((step_interval > 0 && unit->flags.en_step_notify_up) || (step_interval < 0 && unit->flags.en_step_notify_down),
ESP_ERR_INVALID_ARG, TAG, "invalid step interval");
@ -677,7 +679,6 @@ esp_err_t pcnt_unit_add_watch_step(pcnt_unit_handle_t unit, int step_interval)
ESP_RETURN_ON_FALSE(unit->step_interval == 0,
ESP_ERR_INVALID_STATE, TAG, "watch step has been set to %d already", unit->step_interval);
group = unit->group;
unit->step_interval = step_interval;
pcnt_ll_set_step_value(group->hal.dev, unit->unit_id, step_interval);
// different units are mixing in the same register, so we use the group's spinlock here

View File

@ -14,6 +14,7 @@
#include "soc/soc_caps.h"
#include "esp_attr.h"
#include "test_pulse_cnt_board.h"
#include "hal/pcnt_ll.h"
TEST_CASE("pcnt_unit_install_uninstall", "[pcnt]")
{
@ -677,145 +678,148 @@ TEST_CASE("pcnt overflow accumulation", "[pcnt]")
#if SOC_PCNT_SUPPORT_STEP_NOTIFY
TEST_CASE("pcnt_step_notify_event", "[pcnt]")
{
test_gpio_init_for_simulation(TEST_PCNT_GPIO_A);
test_gpio_init_for_simulation(TEST_PCNT_GPIO_B);
if (pcnt_ll_is_step_notify_supported(0)) { // for ESP32H2, only support in chip version v1.2 and above
test_gpio_init_for_simulation(TEST_PCNT_GPIO_A);
test_gpio_init_for_simulation(TEST_PCNT_GPIO_B);
pcnt_unit_config_t unit_config = {
.low_limit = -100,
.high_limit = 100,
.flags = {
.en_step_notify_down = true,
},
};
pcnt_unit_config_t unit_config = {
.low_limit = -100,
.high_limit = 100,
.flags = {
.en_step_notify_down = true,
},
};
printf("install pcnt unit\r\n");
pcnt_unit_handle_t unit = NULL;
TEST_ESP_OK(pcnt_new_unit(&unit_config, &unit));
pcnt_glitch_filter_config_t filter_config = {
.max_glitch_ns = 1000,
};
TEST_ESP_OK(pcnt_unit_set_glitch_filter(unit, &filter_config));
printf("install pcnt unit\r\n");
pcnt_unit_handle_t unit = NULL;
TEST_ESP_OK(pcnt_new_unit(&unit_config, &unit));
pcnt_glitch_filter_config_t filter_config = {
.max_glitch_ns = 1000,
};
TEST_ESP_OK(pcnt_unit_set_glitch_filter(unit, &filter_config));
printf("install two pcnt channels with different edge/level action\r\n");
pcnt_chan_config_t channel_config = {
.edge_gpio_num = TEST_PCNT_GPIO_A,
.level_gpio_num = TEST_PCNT_GPIO_B,
};
pcnt_channel_handle_t channelA = NULL;
TEST_ESP_OK(pcnt_new_channel(unit, &channel_config, &channelA));
TEST_ESP_OK(pcnt_channel_set_edge_action(channelA, PCNT_CHANNEL_EDGE_ACTION_DECREASE, PCNT_CHANNEL_EDGE_ACTION_INCREASE));
TEST_ESP_OK(pcnt_channel_set_level_action(channelA, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_INVERSE));
// switch edge gpio and level gpio, the assign to another channel in the same unit
pcnt_channel_handle_t channelB = NULL;
channel_config.edge_gpio_num = TEST_PCNT_GPIO_B;
channel_config.level_gpio_num = TEST_PCNT_GPIO_A;
TEST_ESP_OK(pcnt_new_channel(unit, &channel_config, &channelB));
TEST_ESP_OK(pcnt_channel_set_edge_action(channelB, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_DECREASE));
TEST_ESP_OK(pcnt_channel_set_level_action(channelB, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_INVERSE));
printf("install two pcnt channels with different edge/level action\r\n");
pcnt_chan_config_t channel_config = {
.edge_gpio_num = TEST_PCNT_GPIO_A,
.level_gpio_num = TEST_PCNT_GPIO_B,
};
pcnt_channel_handle_t channelA = NULL;
TEST_ESP_OK(pcnt_new_channel(unit, &channel_config, &channelA));
TEST_ESP_OK(pcnt_channel_set_edge_action(channelA, PCNT_CHANNEL_EDGE_ACTION_DECREASE, PCNT_CHANNEL_EDGE_ACTION_INCREASE));
TEST_ESP_OK(pcnt_channel_set_level_action(channelA, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_INVERSE));
// switch edge gpio and level gpio, the assign to another channel in the same unit
pcnt_channel_handle_t channelB = NULL;
channel_config.edge_gpio_num = TEST_PCNT_GPIO_B;
channel_config.level_gpio_num = TEST_PCNT_GPIO_A;
TEST_ESP_OK(pcnt_new_channel(unit, &channel_config, &channelB));
TEST_ESP_OK(pcnt_channel_set_edge_action(channelB, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_DECREASE));
TEST_ESP_OK(pcnt_channel_set_level_action(channelB, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_INVERSE));
// ensure the simulation signal in a stable state
TEST_ESP_OK(gpio_set_level(TEST_PCNT_GPIO_A, 1));
TEST_ESP_OK(gpio_set_level(TEST_PCNT_GPIO_B, 1));
// ensure the simulation signal in a stable state
TEST_ESP_OK(gpio_set_level(TEST_PCNT_GPIO_A, 1));
TEST_ESP_OK(gpio_set_level(TEST_PCNT_GPIO_B, 1));
pcnt_event_callbacks_t cbs = {
.on_reach = test_pcnt_quadrature_reach_watch_point,
};
test_pcnt_quadrature_context_t user_data = {
.index = 0,
.triggered_watch_values = {0},
};
TEST_ESP_OK(pcnt_unit_register_event_callbacks(unit, &cbs, &user_data));
pcnt_event_callbacks_t cbs = {
.on_reach = test_pcnt_quadrature_reach_watch_point,
};
test_pcnt_quadrature_context_t user_data = {
.index = 0,
.triggered_watch_values = {0},
};
TEST_ESP_OK(pcnt_unit_register_event_callbacks(unit, &cbs, &user_data));
printf("add watch step and point\r\n");
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, pcnt_unit_add_watch_step(unit, 0));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, pcnt_unit_add_watch_step(unit, 20));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, pcnt_unit_add_watch_step(unit, -120));
TEST_ESP_OK(pcnt_unit_add_watch_step(unit, -25));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, pcnt_unit_add_watch_step(unit, -100));
TEST_ESP_OK(pcnt_unit_add_watch_point(unit, -100));
TEST_ESP_OK(pcnt_unit_add_watch_point(unit, 0));
TEST_ESP_OK(pcnt_unit_add_watch_point(unit, -50));
TEST_ESP_OK(pcnt_unit_add_watch_point(unit, 11));
printf("add watch step and point\r\n");
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, pcnt_unit_add_watch_step(unit, 0));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, pcnt_unit_add_watch_step(unit, 20));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, pcnt_unit_add_watch_step(unit, -120));
TEST_ESP_OK(pcnt_unit_add_watch_step(unit, -25));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, pcnt_unit_add_watch_step(unit, -100));
TEST_ESP_OK(pcnt_unit_add_watch_point(unit, -100));
TEST_ESP_OK(pcnt_unit_add_watch_point(unit, 0));
TEST_ESP_OK(pcnt_unit_add_watch_point(unit, -50));
TEST_ESP_OK(pcnt_unit_add_watch_point(unit, 11));
TEST_ESP_OK(pcnt_unit_enable(unit));
TEST_ESP_OK(pcnt_unit_start(unit));
TEST_ESP_OK(pcnt_unit_enable(unit));
TEST_ESP_OK(pcnt_unit_start(unit));
printf("simulating quadrature signals and count down\r\n");
test_gpio_simulate_quadrature_signals(TEST_PCNT_GPIO_A, TEST_PCNT_GPIO_B, 25); // 25*(-4) = -100 -> 0
printf("simulating quadrature signals and count down\r\n");
test_gpio_simulate_quadrature_signals(TEST_PCNT_GPIO_A, TEST_PCNT_GPIO_B, 25); // 25*(-4) = -100 -> 0
int count_value;
TEST_ESP_OK(pcnt_unit_get_count(unit, &count_value));
printf("counter stopped at %d\r\n", count_value);
int count_value;
TEST_ESP_OK(pcnt_unit_get_count(unit, &count_value));
printf("counter stopped at %d\r\n", count_value);
for (int i = 0 ; i < user_data.index; i++) {
printf("%d:%d\r\n", i, user_data.triggered_watch_values[i]);
for (int i = 0 ; i < user_data.index; i++) {
printf("%d:%d\r\n", i, user_data.triggered_watch_values[i]);
}
TEST_ASSERT_EQUAL(0, count_value);
TEST_ASSERT_EQUAL(5, user_data.index);
TEST_ASSERT_EQUAL(-25, user_data.triggered_watch_values[0]); // step point (-25*1)
TEST_ASSERT_EQUAL(-50, user_data.triggered_watch_values[1]); // step point && watch point
TEST_ASSERT_EQUAL(-75, user_data.triggered_watch_values[2]); // step point (-25*3)
TEST_ASSERT_EQUAL(-100, user_data.triggered_watch_values[3]);// step point && watch point
TEST_ASSERT_EQUAL(0, user_data.triggered_watch_values[4]); // watch point (overflow zero cross)
printf("simulating quadrature signals and count up\r\n");
user_data.index = 0;
test_gpio_simulate_quadrature_signals(TEST_PCNT_GPIO_B, TEST_PCNT_GPIO_A, 3); // 0+3*4 = 12
TEST_ESP_OK(pcnt_unit_get_count(unit, &count_value));
printf("counter stopped at %d\r\n", count_value);
for (int i = 0 ; i < user_data.index; i++) {
printf("%d:%d\r\n", i, user_data.triggered_watch_values[i]);
}
TEST_ASSERT_EQUAL(12, count_value);
TEST_ASSERT_EQUAL(1, user_data.index);
TEST_ASSERT_EQUAL(11, user_data.triggered_watch_values[0]); // watch point
printf("simulating quadrature signals and count down again\r\n");
user_data.index = 0;
test_gpio_simulate_quadrature_signals(TEST_PCNT_GPIO_A, TEST_PCNT_GPIO_B, 13); // 12-13*4 = -40
TEST_ESP_OK(pcnt_unit_get_count(unit, &count_value));
printf("counter stopped at %d\r\n", count_value);
for (int i = 0 ; i < user_data.index; i++) {
printf("%d:%d\r\n", i, user_data.triggered_watch_values[i]);
}
TEST_ASSERT_EQUAL(-40, count_value);
TEST_ASSERT_EQUAL(3, user_data.index);
TEST_ASSERT_EQUAL(11, user_data.triggered_watch_values[0]); // watch point
TEST_ASSERT_EQUAL(0, user_data.triggered_watch_values[1]); // watch point (zero cross)
TEST_ASSERT_EQUAL(-25, user_data.triggered_watch_values[2]);// step point (-25*1)
// before change step interval, the next step point should be -25-25=-50
printf("change step interval\r\n");
TEST_ESP_OK(pcnt_unit_remove_watch_step(unit));
TEST_ESP_OK(pcnt_unit_add_watch_step(unit, -20));
// but after change, the next step point is -25-20=-45 (-25 is the last active step point)
printf("simulating quadrature signals and count down\r\n");
user_data.index = 0;
test_gpio_simulate_quadrature_signals(TEST_PCNT_GPIO_A, TEST_PCNT_GPIO_B, 20); // -40+20*(-4) = -120 -> -20
TEST_ESP_OK(pcnt_unit_get_count(unit, &count_value));
printf("counter stopped at %d\r\n", count_value);
for (int i = 0 ; i < user_data.index; i++) {
printf("%d:%d\r\n", i, user_data.triggered_watch_values[i]);
}
TEST_ASSERT_EQUAL(-20, count_value);
TEST_ASSERT_EQUAL(7, user_data.index);
TEST_ASSERT_EQUAL(-45, user_data.triggered_watch_values[0]); // watch step
TEST_ASSERT_EQUAL(-50, user_data.triggered_watch_values[1]); // watch point
TEST_ASSERT_EQUAL(-65, user_data.triggered_watch_values[2]); // step point (-45-20)
TEST_ASSERT_EQUAL(-85, user_data.triggered_watch_values[3]); // step point (-65-20)
TEST_ASSERT_EQUAL(-100, user_data.triggered_watch_values[4]);// step && watch point
TEST_ASSERT_EQUAL(0, user_data.triggered_watch_values[5]); // watch point (overflow)
TEST_ASSERT_EQUAL(-20, user_data.triggered_watch_values[6]); // step point (0-20)
printf("remove step_notify and uninstall channels\r\n");
TEST_ESP_OK(pcnt_unit_remove_watch_step(unit));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, pcnt_unit_remove_watch_step(unit));
TEST_ESP_OK(pcnt_del_channel(channelA));
TEST_ESP_OK(pcnt_del_channel(channelB));
TEST_ESP_OK(pcnt_unit_stop(unit));
TEST_ESP_OK(pcnt_unit_disable(unit));
TEST_ESP_OK(pcnt_del_unit(unit));
}
TEST_ASSERT_EQUAL(0, count_value);
TEST_ASSERT_EQUAL(5, user_data.index);
TEST_ASSERT_EQUAL(-25, user_data.triggered_watch_values[0]); // step point (-25*1)
TEST_ASSERT_EQUAL(-50, user_data.triggered_watch_values[1]); // step point && watch point
TEST_ASSERT_EQUAL(-75, user_data.triggered_watch_values[2]); // step point (-25*3)
TEST_ASSERT_EQUAL(-100, user_data.triggered_watch_values[3]);// step point && watch point
TEST_ASSERT_EQUAL(0, user_data.triggered_watch_values[4]); // watch point (overflow zero cross)
printf("simulating quadrature signals and count up\r\n");
user_data.index = 0;
test_gpio_simulate_quadrature_signals(TEST_PCNT_GPIO_B, TEST_PCNT_GPIO_A, 3); // 0+3*4 = 12
TEST_ESP_OK(pcnt_unit_get_count(unit, &count_value));
printf("counter stopped at %d\r\n", count_value);
for (int i = 0 ; i < user_data.index; i++) {
printf("%d:%d\r\n", i, user_data.triggered_watch_values[i]);
}
TEST_ASSERT_EQUAL(12, count_value);
TEST_ASSERT_EQUAL(1, user_data.index);
TEST_ASSERT_EQUAL(11, user_data.triggered_watch_values[0]); // watch point
printf("simulating quadrature signals and count down again\r\n");
user_data.index = 0;
test_gpio_simulate_quadrature_signals(TEST_PCNT_GPIO_A, TEST_PCNT_GPIO_B, 13); // 12-13*4 = -40
TEST_ESP_OK(pcnt_unit_get_count(unit, &count_value));
printf("counter stopped at %d\r\n", count_value);
for (int i = 0 ; i < user_data.index; i++) {
printf("%d:%d\r\n", i, user_data.triggered_watch_values[i]);
}
TEST_ASSERT_EQUAL(-40, count_value);
TEST_ASSERT_EQUAL(3, user_data.index);
TEST_ASSERT_EQUAL(11, user_data.triggered_watch_values[0]); // watch point
TEST_ASSERT_EQUAL(0, user_data.triggered_watch_values[1]); // watch point (zero cross)
TEST_ASSERT_EQUAL(-25, user_data.triggered_watch_values[2]);// step point (-25*1)
// before change step interval, the next step point should be -25-25=-50
printf("change step interval\r\n");
TEST_ESP_OK(pcnt_unit_remove_watch_step(unit));
TEST_ESP_OK(pcnt_unit_add_watch_step(unit, -20));
// but after change, the next step point is -25-20=-45 (-25 is the last active step point)
printf("simulating quadrature signals and count down\r\n");
user_data.index = 0;
test_gpio_simulate_quadrature_signals(TEST_PCNT_GPIO_A, TEST_PCNT_GPIO_B, 20); // -40+20*(-4) = -120 -> -20
TEST_ESP_OK(pcnt_unit_get_count(unit, &count_value));
printf("counter stopped at %d\r\n", count_value);
for (int i = 0 ; i < user_data.index; i++) {
printf("%d:%d\r\n", i, user_data.triggered_watch_values[i]);
}
TEST_ASSERT_EQUAL(-20, count_value);
TEST_ASSERT_EQUAL(7, user_data.index);
TEST_ASSERT_EQUAL(-45, user_data.triggered_watch_values[0]); // watch step
TEST_ASSERT_EQUAL(-50, user_data.triggered_watch_values[1]); // watch point
TEST_ASSERT_EQUAL(-65, user_data.triggered_watch_values[2]); // step point (-45-20)
TEST_ASSERT_EQUAL(-85, user_data.triggered_watch_values[3]); // step point (-65-20)
TEST_ASSERT_EQUAL(-100, user_data.triggered_watch_values[4]);// step && watch point
TEST_ASSERT_EQUAL(0, user_data.triggered_watch_values[5]); // watch point (overflow)
TEST_ASSERT_EQUAL(-20, user_data.triggered_watch_values[6]); // step point (0-20)
printf("remove step_notify and uninstall channels\r\n");
TEST_ESP_OK(pcnt_unit_remove_watch_step(unit));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, pcnt_unit_remove_watch_step(unit));
TEST_ESP_OK(pcnt_del_channel(channelA));
TEST_ESP_OK(pcnt_del_channel(channelB));
TEST_ESP_OK(pcnt_unit_stop(unit));
TEST_ESP_OK(pcnt_unit_disable(unit));
TEST_ESP_OK(pcnt_del_unit(unit));
}
#endif // SOC_PCNT_SUPPORT_STEP_NOTIFY

View File

@ -497,6 +497,16 @@ static inline void pcnt_ll_reset_register(int group_id)
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

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -19,6 +19,9 @@
#include <stdbool.h>
#include "soc/pcnt_struct.h"
#include "hal/pcnt_types.h"
#include "hal/misc.h"
#include "hal/efuse_hal.h"
#include "soc/chip_revision.h"
#include "soc/pcr_struct.h"
#ifdef __cplusplus
@ -40,6 +43,12 @@ typedef enum {
PCNT_LL_WATCH_EVENT_MAX
} pcnt_ll_watch_event_id_t;
typedef enum {
PCNT_LL_STEP_EVENT_REACH_LIMIT = PCNT_LL_WATCH_EVENT_MAX,
PCNT_LL_STEP_EVENT_REACH_INTERVAL
} pcnt_ll_step_event_id_t;
#define PCNT_LL_STEP_NOTIFY_DIR_LIMIT 1
#define PCNT_LL_WATCH_EVENT_MASK ((1 << PCNT_LL_WATCH_EVENT_MAX) - 1)
#define PCNT_LL_UNIT_WATCH_EVENT(unit_id) (1 << (unit_id))
@ -137,6 +146,46 @@ static inline void pcnt_ll_clear_count(pcnt_dev_t *hw, uint32_t 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 value PCNT step value
*/
static inline void pcnt_ll_set_step_value(pcnt_dev_t *hw, uint32_t unit, int value)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->change_conf_unit[3 - unit], cnt_step, value);
}
/**
* @brief Set PCNT step limit value
*
* @param hw Peripheral PCNT hardware instance address.
* @param unit PCNT unit number
* @param value PCNT step limit value
*/
static inline void pcnt_ll_set_step_limit_value(pcnt_dev_t *hw, uint32_t unit, int value)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->change_conf_unit[3 - unit], cnt_step_lim, value);
}
/**
* @brief Enable PCNT interrupt for PCNT unit
* @note Each PCNT unit has five watch point events that share the same interrupt bit.
@ -458,6 +507,16 @@ static inline void pcnt_ll_reset_register(int group_id)
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 ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102);
}
#ifdef __cplusplus
}
#endif

View File

@ -763,6 +763,10 @@ config SOC_PCNT_SUPPORT_RUNTIME_THRES_UPDATE
bool
default y
config SOC_PCNT_SUPPORT_STEP_NOTIFY
bool
default y
config SOC_PCNT_SUPPORT_SLEEP_RETENTION
bool
default y

View File

@ -302,6 +302,7 @@
#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_STEP_NOTIFY 1 /*!< Only avliable in chip version above 1.2*/
#define SOC_PCNT_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up PCNT registers before sleep */
/*--------------------------- RMT CAPS ---------------------------------------*/

View File

@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -181,7 +181,23 @@ typedef union {
* Set this bit to freeze unit 3's counter.
*/
uint32_t cnt_pause_u3:1;
uint32_t reserved_8:8;
/** dalta_change_en_u0 : R/W; bitpos: [8]; default: 0;
* Configures this bit to enable unit 0's step comparator.
*/
uint32_t dalta_change_en_u0:1;
/** dalta_change_en_u1 : R/W; bitpos: [9]; default: 0;
* Configures this bit to enable unit 1's step comparator.
*/
uint32_t dalta_change_en_u1:1;
/** dalta_change_en_u2 : R/W; bitpos: [10]; default: 0;
* Configures this bit to enable unit 2's step comparator.
*/
uint32_t dalta_change_en_u2:1;
/** dalta_change_en_u3 : R/W; bitpos: [11]; default: 0;
* Configures this bit to enable unit 3's step comparator.
*/
uint32_t dalta_change_en_u3:1;
uint32_t reserved_12:4;
/** clk_en : R/W; bitpos: [16]; default: 0;
* The registers clock gate enable signal of PCNT module. 1: the registers can be read
* and written by application. 0: the registers can not be read or written by
@ -193,6 +209,22 @@ typedef union {
uint32_t val;
} pcnt_ctrl_reg_t;
/** Type of change_conf register
* Configuration register for unit $n's step value.
*/
typedef union {
struct {
/** cnt_step : R/W; bitpos: [15:0]; default: 0;
* Configures the step value for unit n.
*/
uint32_t cnt_step:16;
/** cnt_step_lim : R/W; bitpos: [31:16]; default: 0;
* Configures the step limit value for unit n.
*/
uint32_t cnt_step_lim:16;
};
uint32_t val;
} pcnt_un_change_conf_reg_t;
/** Group: Status Register */
/** Type of un_cnt register
@ -250,7 +282,19 @@ typedef union {
* valid. 0: others
*/
uint32_t cnt_thr_zero_lat:1;
uint32_t reserved_7:25;
/** cnt_thr_step_lim_lat_un : RO; bitpos: [7]; default: 0;
* The latched value of step counter limit event of PCNT_Un when step counter event
* interrupt is valid. 1: the current pulse counter equals to reg_cnt_step_lim and
* step counter event is valid. 0: others
*/
uint32_t cnt_thr_step_lim_lat_un:1;
/** cnt_thr_step_lat_un : RO; bitpos: [8]; default: 0;
* The latched value of step counter event of PCNT_Un when step counter event
* interrupt is valid. 1: the current pulse counter increment equals to reg_cnt_step
* and step counter event is valid. 0: others
*/
uint32_t cnt_thr_step_lat_un:1;
uint32_t reserved_7:23;
};
uint32_t val;
} pcnt_un_status_reg_t;
@ -389,7 +433,8 @@ typedef struct pcnt_dev_t {
volatile pcnt_int_clr_reg_t int_clr;
volatile pcnt_un_status_reg_t status_unit[4];
volatile pcnt_ctrl_reg_t ctrl;
uint32_t reserved_064[38];
volatile pcnt_un_change_conf_reg_t change_conf_unit[4]; // Note the unit order is 3210
uint32_t reserved_064[34];
volatile pcnt_date_reg_t date;
} pcnt_dev_t;