forked from espressif/esp-idf
feat(pcnt): re-support pcnt on ESP32-C5 V1.0
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -316,7 +316,7 @@ esp_err_t pcnt_unit_remove_watch_point(pcnt_unit_handle_t unit, int watch_point)
|
|||||||
* @brief Add a step notify for PCNT unit, PCNT will generate an event when the incremental(can be positive or negative) of counter value reaches the step interval
|
* @brief Add a step notify for PCNT unit, PCNT will generate an event when the incremental(can be positive or negative) of counter value reaches the step interval
|
||||||
*
|
*
|
||||||
* @param[in] unit PCNT unit handle created by `pcnt_new_unit()`
|
* @param[in] unit PCNT unit handle created by `pcnt_new_unit()`
|
||||||
* @param[in] step_interval PCNT step notify interval value
|
* @param[in] step_interval PCNT step notify interval value. Positive value means step forward, negative value means step backward.
|
||||||
* @return
|
* @return
|
||||||
* - ESP_OK: Add step notify successfully
|
* - ESP_OK: Add step notify successfully
|
||||||
* - ESP_ERR_INVALID_ARG: Add step notify failed because of invalid argument (e.g. the value incremental to be watched is out of the limitation set in `pcnt_unit_config_t`)
|
* - ESP_ERR_INVALID_ARG: Add step notify failed because of invalid argument (e.g. the value incremental to be watched is out of the limitation set in `pcnt_unit_config_t`)
|
||||||
@@ -326,7 +326,7 @@ esp_err_t pcnt_unit_remove_watch_point(pcnt_unit_handle_t unit, int watch_point)
|
|||||||
esp_err_t pcnt_unit_add_watch_step(pcnt_unit_handle_t unit, int step_interval);
|
esp_err_t pcnt_unit_add_watch_step(pcnt_unit_handle_t unit, int step_interval);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remove a step notify for PCNT unit
|
* @brief Remove all step notify for PCNT unit
|
||||||
*
|
*
|
||||||
* @param[in] unit PCNT unit handle created by `pcnt_new_unit()`
|
* @param[in] unit PCNT unit handle created by `pcnt_new_unit()`
|
||||||
* @return
|
* @return
|
||||||
@@ -335,7 +335,25 @@ esp_err_t pcnt_unit_add_watch_step(pcnt_unit_handle_t unit, int step_interval);
|
|||||||
* - ESP_ERR_INVALID_STATE: Remove step notify failed because the step notify was not added by `pcnt_unit_add_watch_step()` yet
|
* - ESP_ERR_INVALID_STATE: Remove step notify failed because the step notify was not added by `pcnt_unit_add_watch_step()` yet
|
||||||
* - ESP_FAIL: Remove step notify failed because of other error
|
* - ESP_FAIL: Remove step notify failed because of other error
|
||||||
*/
|
*/
|
||||||
esp_err_t pcnt_unit_remove_watch_step(pcnt_unit_handle_t unit);
|
esp_err_t pcnt_unit_remove_all_watch_step(pcnt_unit_handle_t unit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Remove a step notify for PCNT unit
|
||||||
|
*
|
||||||
|
* @param[in] unit PCNT unit handle created by `pcnt_new_unit()`
|
||||||
|
* @param[in] step_interval Step notify interval value
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: Remove step notify successfully
|
||||||
|
* - ESP_ERR_INVALID_ARG: Remove step notify failed because of invalid argument
|
||||||
|
* - ESP_ERR_INVALID_STATE: Remove step notify failed because the step notify was not added by `pcnt_unit_add_watch_step()` yet
|
||||||
|
* - ESP_FAIL: Remove step notify failed because of other error
|
||||||
|
*/
|
||||||
|
esp_err_t pcnt_unit_remove_single_watch_step(pcnt_unit_handle_t unit, int step_interval);
|
||||||
|
|
||||||
|
#define _pcnt_unit_remove_all_watch_step(unit) pcnt_unit_remove_all_watch_step(unit)
|
||||||
|
#define _pcnt_unit_remove_single_watch_step(unit, step_interval) pcnt_unit_remove_single_watch_step(unit, step_interval)
|
||||||
|
#define _pcnt_get_remove_func(_1, _2, FUNC, ...) FUNC
|
||||||
|
#define pcnt_unit_remove_watch_step(...) _pcnt_get_remove_func(__VA_ARGS__, _pcnt_unit_remove_single_watch_step, _pcnt_unit_remove_all_watch_step)(__VA_ARGS__)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create PCNT channel for specific unit, each PCNT has several channels associated with it
|
* @brief Create PCNT channel for specific unit, each PCNT has several channels associated with it
|
||||||
|
@@ -92,6 +92,16 @@ typedef struct {
|
|||||||
int watch_point_value; // value to be watched
|
int watch_point_value; // value to be watched
|
||||||
} pcnt_watch_point_t;
|
} pcnt_watch_point_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
#if PCNT_LL_STEP_NOTIFY_DIR_LIMIT
|
||||||
|
int step_interval; // step interval
|
||||||
|
int step_limit; // step limit value
|
||||||
|
#else
|
||||||
|
int step_interval_forward; // step interval for forward direction
|
||||||
|
int step_interval_backward; // step interval for backward direction
|
||||||
|
#endif
|
||||||
|
} pcnt_step_interval_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PCNT_UNIT_FSM_INIT,
|
PCNT_UNIT_FSM_INIT,
|
||||||
PCNT_UNIT_FSM_ENABLE,
|
PCNT_UNIT_FSM_ENABLE,
|
||||||
@@ -103,10 +113,9 @@ struct pcnt_unit_t {
|
|||||||
int unit_id; // allocated unit numerical ID
|
int unit_id; // allocated unit numerical ID
|
||||||
int low_limit; // low limit value
|
int low_limit; // low limit value
|
||||||
int high_limit; // high limit value
|
int high_limit; // high limit value
|
||||||
int step_limit; // step limit value
|
|
||||||
int clear_signal_gpio_num; // which gpio clear signal input
|
int clear_signal_gpio_num; // which gpio clear signal input
|
||||||
int accum_value; // accumulated count value
|
int accum_value; // accumulated count value
|
||||||
int step_interval; // PCNT step notify interval value
|
pcnt_step_interval_t step_info; // step interval info
|
||||||
pcnt_chan_t *channels[SOC_PCNT_CHANNELS_PER_UNIT]; // array of PCNT channels
|
pcnt_chan_t *channels[SOC_PCNT_CHANNELS_PER_UNIT]; // array of PCNT channels
|
||||||
pcnt_watch_point_t watchers[PCNT_LL_WATCH_EVENT_MAX]; // array of PCNT watchers
|
pcnt_watch_point_t watchers[PCNT_LL_WATCH_EVENT_MAX]; // array of PCNT watchers
|
||||||
intr_handle_t intr; // interrupt handle
|
intr_handle_t intr; // interrupt handle
|
||||||
@@ -281,11 +290,11 @@ esp_err_t pcnt_new_unit(const pcnt_unit_config_t *config, pcnt_unit_handle_t *re
|
|||||||
unit->flags.en_step_notify_up = config->flags.en_step_notify_up;
|
unit->flags.en_step_notify_up = config->flags.en_step_notify_up;
|
||||||
#if PCNT_LL_STEP_NOTIFY_DIR_LIMIT
|
#if PCNT_LL_STEP_NOTIFY_DIR_LIMIT
|
||||||
if (config->flags.en_step_notify_up) {
|
if (config->flags.en_step_notify_up) {
|
||||||
unit->step_limit = config->high_limit;
|
unit->step_info.step_limit = config->high_limit;
|
||||||
} else if (config->flags.en_step_notify_down) {
|
} else if (config->flags.en_step_notify_down) {
|
||||||
unit->step_limit = config->low_limit;
|
unit->step_info.step_limit = config->low_limit;
|
||||||
}
|
}
|
||||||
pcnt_ll_set_step_limit_value(group->hal.dev, unit_id, unit->step_limit);
|
pcnt_ll_set_step_limit_value(group->hal.dev, unit_id, unit->step_info.step_limit);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -679,11 +688,26 @@ esp_err_t pcnt_unit_add_watch_step(pcnt_unit_handle_t unit, int step_interval)
|
|||||||
ESP_ERR_INVALID_ARG, TAG, "invalid step interval");
|
ESP_ERR_INVALID_ARG, TAG, "invalid step interval");
|
||||||
ESP_RETURN_ON_FALSE(step_interval >= unit->low_limit && step_interval <= unit->high_limit,
|
ESP_RETURN_ON_FALSE(step_interval >= unit->low_limit && step_interval <= unit->high_limit,
|
||||||
ESP_ERR_INVALID_ARG, TAG, "step interval out of range [%d,%d]", unit->low_limit, unit->high_limit);
|
ESP_ERR_INVALID_ARG, TAG, "step interval out of range [%d,%d]", unit->low_limit, unit->high_limit);
|
||||||
ESP_RETURN_ON_FALSE(unit->step_interval == 0,
|
|
||||||
ESP_ERR_INVALID_STATE, TAG, "watch step has been set to %d already", unit->step_interval);
|
|
||||||
|
|
||||||
unit->step_interval = step_interval;
|
#if PCNT_LL_STEP_NOTIFY_DIR_LIMIT
|
||||||
pcnt_ll_set_step_value(group->hal.dev, unit->unit_id, step_interval);
|
ESP_RETURN_ON_FALSE(unit->step_info.step_interval == 0,
|
||||||
|
ESP_ERR_INVALID_STATE, TAG, "watch step has been set to %d already", unit->step_info.step_interval);
|
||||||
|
pcnt_ll_set_step_value(group->hal.dev, unit->unit_id, step_interval > 0 ? PCNT_STEP_FORWARD : PCNT_STEP_BACKWARD, (uint16_t)step_interval);
|
||||||
|
unit->step_info.step_interval = step_interval;
|
||||||
|
#else
|
||||||
|
if (step_interval > 0) {
|
||||||
|
ESP_RETURN_ON_FALSE(unit->step_info.step_interval_forward == 0,
|
||||||
|
ESP_ERR_INVALID_STATE, TAG, "watch step in forward has been set to %d already", unit->step_info.step_interval_forward);
|
||||||
|
pcnt_ll_set_step_value(group->hal.dev, unit->unit_id, PCNT_STEP_FORWARD, (uint16_t)step_interval);
|
||||||
|
unit->step_info.step_interval_forward = step_interval;
|
||||||
|
} else {
|
||||||
|
ESP_RETURN_ON_FALSE(unit->step_info.step_interval_backward == 0,
|
||||||
|
ESP_ERR_INVALID_STATE, TAG, "watch step in backward has been set to %d already", unit->step_info.step_interval_backward);
|
||||||
|
pcnt_ll_set_step_value(group->hal.dev, unit->unit_id, PCNT_STEP_BACKWARD, (uint16_t)step_interval);
|
||||||
|
unit->step_info.step_interval_backward = step_interval;
|
||||||
|
}
|
||||||
|
#endif //PCNT_LL_STEP_NOTIFY_DIR_LIMIT
|
||||||
|
|
||||||
// different units are mixing in the same register, so we use the group's spinlock here
|
// different units are mixing in the same register, so we use the group's spinlock here
|
||||||
portENTER_CRITICAL(&group->spinlock);
|
portENTER_CRITICAL(&group->spinlock);
|
||||||
pcnt_ll_enable_step_notify(group->hal.dev, unit->unit_id, true);
|
pcnt_ll_enable_step_notify(group->hal.dev, unit->unit_id, true);
|
||||||
@@ -692,14 +716,20 @@ esp_err_t pcnt_unit_add_watch_step(pcnt_unit_handle_t unit, int step_interval)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t pcnt_unit_remove_watch_step(pcnt_unit_handle_t unit)
|
esp_err_t pcnt_unit_remove_all_watch_step(pcnt_unit_handle_t unit)
|
||||||
{
|
{
|
||||||
pcnt_group_t *group = NULL;
|
pcnt_group_t *group = NULL;
|
||||||
ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||||
group = unit->group;
|
group = unit->group;
|
||||||
ESP_RETURN_ON_FALSE(unit->step_interval != 0, ESP_ERR_INVALID_STATE, TAG, "watch step not added yet");
|
#if PCNT_LL_STEP_NOTIFY_DIR_LIMIT
|
||||||
|
ESP_RETURN_ON_FALSE(unit->step_info.step_interval != 0, ESP_ERR_INVALID_STATE, TAG, "watch step not added yet");
|
||||||
unit->step_interval = 0;
|
unit->step_info.step_interval = 0;
|
||||||
|
#else
|
||||||
|
ESP_RETURN_ON_FALSE(unit->step_info.step_interval_forward != 0 || unit->step_info.step_interval_backward != 0,
|
||||||
|
ESP_ERR_INVALID_STATE, TAG, "watch step in forward or backward not added yet");
|
||||||
|
unit->step_info.step_interval_forward = 0;
|
||||||
|
unit->step_info.step_interval_backward = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
portENTER_CRITICAL(&group->spinlock);
|
portENTER_CRITICAL(&group->spinlock);
|
||||||
pcnt_ll_enable_step_notify(group->hal.dev, unit->unit_id, false);
|
pcnt_ll_enable_step_notify(group->hal.dev, unit->unit_id, false);
|
||||||
@@ -707,6 +737,36 @@ esp_err_t pcnt_unit_remove_watch_step(pcnt_unit_handle_t unit)
|
|||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t pcnt_unit_remove_single_watch_step(pcnt_unit_handle_t unit, int step_interval)
|
||||||
|
{
|
||||||
|
pcnt_group_t *group = NULL;
|
||||||
|
ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||||
|
group = unit->group;
|
||||||
|
#if PCNT_LL_STEP_NOTIFY_DIR_LIMIT
|
||||||
|
ESP_RETURN_ON_FALSE(unit->step_info.step_interval == step_interval, ESP_ERR_INVALID_STATE, TAG, "watch step %d not added yet", step_interval);
|
||||||
|
unit->step_info.step_interval = 0;
|
||||||
|
portENTER_CRITICAL(&group->spinlock);
|
||||||
|
pcnt_ll_enable_step_notify(group->hal.dev, unit->unit_id, false);
|
||||||
|
portEXIT_CRITICAL(&group->spinlock);
|
||||||
|
#else
|
||||||
|
if (step_interval > 0) {
|
||||||
|
ESP_RETURN_ON_FALSE(unit->step_info.step_interval_forward == step_interval, ESP_ERR_INVALID_STATE, TAG, "watch step %d not added yet", step_interval);
|
||||||
|
pcnt_ll_set_step_value(group->hal.dev, unit->unit_id, PCNT_STEP_FORWARD, 0);
|
||||||
|
unit->step_info.step_interval_forward = 0;
|
||||||
|
} else {
|
||||||
|
ESP_RETURN_ON_FALSE(unit->step_info.step_interval_backward == step_interval, ESP_ERR_INVALID_STATE, TAG, "watch step %d not added yet", step_interval);
|
||||||
|
pcnt_ll_set_step_value(group->hal.dev, unit->unit_id, PCNT_STEP_BACKWARD, 0);
|
||||||
|
unit->step_info.step_interval_backward = 0;
|
||||||
|
}
|
||||||
|
if (unit->step_info.step_interval_forward == 0 && unit->step_info.step_interval_backward == 0) {
|
||||||
|
portENTER_CRITICAL(&group->spinlock);
|
||||||
|
pcnt_ll_enable_step_notify(group->hal.dev, unit->unit_id, false);
|
||||||
|
portEXIT_CRITICAL(&group->spinlock);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
#endif //SOC_PCNT_SUPPORT_STEP_NOTIFY
|
#endif //SOC_PCNT_SUPPORT_STEP_NOTIFY
|
||||||
|
|
||||||
esp_err_t pcnt_new_channel(pcnt_unit_handle_t unit, const pcnt_chan_config_t *config, pcnt_channel_handle_t *ret_chan)
|
esp_err_t pcnt_new_channel(pcnt_unit_handle_t unit, const pcnt_chan_config_t *config, pcnt_channel_handle_t *ret_chan)
|
||||||
@@ -962,6 +1022,7 @@ IRAM_ATTR static void pcnt_default_isr(void *args)
|
|||||||
// using while loop so that we don't miss any event
|
// using while loop so that we don't miss any event
|
||||||
while (event_status) {
|
while (event_status) {
|
||||||
#if SOC_PCNT_SUPPORT_STEP_NOTIFY
|
#if SOC_PCNT_SUPPORT_STEP_NOTIFY
|
||||||
|
#if PCNT_LL_STEP_NOTIFY_DIR_LIMIT
|
||||||
// step event has higher priority than pointer event
|
// step event has higher priority than pointer event
|
||||||
if (event_status & (BIT(PCNT_LL_STEP_EVENT_REACH_INTERVAL) | BIT(PCNT_LL_STEP_EVENT_REACH_LIMIT))) {
|
if (event_status & (BIT(PCNT_LL_STEP_EVENT_REACH_INTERVAL) | BIT(PCNT_LL_STEP_EVENT_REACH_LIMIT))) {
|
||||||
if (event_status & BIT(PCNT_LL_STEP_EVENT_REACH_INTERVAL)) {
|
if (event_status & BIT(PCNT_LL_STEP_EVENT_REACH_INTERVAL)) {
|
||||||
@@ -972,13 +1033,27 @@ IRAM_ATTR static void pcnt_default_isr(void *args)
|
|||||||
if (event_status & BIT(PCNT_LL_STEP_EVENT_REACH_LIMIT)) {
|
if (event_status & BIT(PCNT_LL_STEP_EVENT_REACH_LIMIT)) {
|
||||||
event_status &= ~BIT(PCNT_LL_STEP_EVENT_REACH_LIMIT);
|
event_status &= ~BIT(PCNT_LL_STEP_EVENT_REACH_LIMIT);
|
||||||
// adjust current count value to the step limit
|
// adjust current count value to the step limit
|
||||||
count_value = unit->step_limit;
|
count_value = unit->step_info.step_limit;
|
||||||
if (unit->flags.accum_count) {
|
if (unit->flags.accum_count) {
|
||||||
portENTER_CRITICAL_ISR(&unit->spinlock);
|
portENTER_CRITICAL_ISR(&unit->spinlock);
|
||||||
unit->accum_value += unit->step_limit;
|
unit->accum_value += unit->step_info.step_limit;
|
||||||
portEXIT_CRITICAL_ISR(&unit->spinlock);
|
portEXIT_CRITICAL_ISR(&unit->spinlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// step event has higher priority than pointer event
|
||||||
|
if (event_status & (BIT(PCNT_LL_STEP_EVENT_REACH_INTERVAL_FORWARD) | BIT(PCNT_LL_STEP_EVENT_REACH_INTERVAL_BACKWARD))) {
|
||||||
|
if (event_status & BIT(PCNT_LL_STEP_EVENT_REACH_INTERVAL_FORWARD)) {
|
||||||
|
event_status &= ~BIT(PCNT_LL_STEP_EVENT_REACH_INTERVAL_FORWARD);
|
||||||
|
// align current count value to the step interval
|
||||||
|
count_value = pcnt_ll_get_count(group->hal.dev, unit_id);
|
||||||
|
}
|
||||||
|
if (event_status & BIT(PCNT_LL_STEP_EVENT_REACH_INTERVAL_BACKWARD)) {
|
||||||
|
event_status &= ~BIT(PCNT_LL_STEP_EVENT_REACH_INTERVAL_BACKWARD);
|
||||||
|
// align current count value to the step interval
|
||||||
|
count_value = pcnt_ll_get_count(group->hal.dev, unit_id);
|
||||||
|
}
|
||||||
|
#endif // PCNT_LL_STEP_NOTIFY_DIR_LIMIT
|
||||||
// step event may happen with other pointer event at the same time, we don't need to process them again
|
// step event may happen with other pointer event at the same time, we don't need to process them again
|
||||||
event_status &= ~(BIT(PCNT_LL_WATCH_EVENT_LOW_LIMIT) | BIT(PCNT_LL_WATCH_EVENT_HIGH_LIMIT) |
|
event_status &= ~(BIT(PCNT_LL_WATCH_EVENT_LOW_LIMIT) | BIT(PCNT_LL_WATCH_EVENT_HIGH_LIMIT) |
|
||||||
BIT(PCNT_LL_WATCH_EVENT_THRES0) | BIT(PCNT_LL_WATCH_EVENT_THRES1));
|
BIT(PCNT_LL_WATCH_EVENT_THRES0) | BIT(PCNT_LL_WATCH_EVENT_THRES1));
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -681,6 +681,9 @@ TEST_CASE("pcnt_step_notify_event", "[pcnt]")
|
|||||||
if (pcnt_ll_is_step_notify_supported(0)) { // for ESP32H2, only support in chip version v1.2 and above
|
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_A);
|
||||||
test_gpio_init_for_simulation(TEST_PCNT_GPIO_B);
|
test_gpio_init_for_simulation(TEST_PCNT_GPIO_B);
|
||||||
|
// 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_unit_config_t unit_config = {
|
pcnt_unit_config_t unit_config = {
|
||||||
.low_limit = -100,
|
.low_limit = -100,
|
||||||
@@ -715,10 +718,6 @@ TEST_CASE("pcnt_step_notify_event", "[pcnt]")
|
|||||||
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_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));
|
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));
|
|
||||||
|
|
||||||
pcnt_event_callbacks_t cbs = {
|
pcnt_event_callbacks_t cbs = {
|
||||||
.on_reach = test_pcnt_quadrature_reach_watch_point,
|
.on_reach = test_pcnt_quadrature_reach_watch_point,
|
||||||
};
|
};
|
||||||
@@ -820,6 +819,141 @@ TEST_CASE("pcnt_step_notify_event", "[pcnt]")
|
|||||||
TEST_ESP_OK(pcnt_unit_disable(unit));
|
TEST_ESP_OK(pcnt_unit_disable(unit));
|
||||||
TEST_ESP_OK(pcnt_del_unit(unit));
|
TEST_ESP_OK(pcnt_del_unit(unit));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !PCNT_LL_STEP_NOTIFY_DIR_LIMIT
|
||||||
|
TEST_CASE("pcnt_step_notify_event_bidirectional", "[pcnt]")
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
// 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_unit_config_t unit_config = {
|
||||||
|
.low_limit = -100,
|
||||||
|
.high_limit = 100,
|
||||||
|
.flags = {
|
||||||
|
.en_step_notify_down = true,
|
||||||
|
.en_step_notify_up = 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 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));
|
||||||
|
|
||||||
|
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_ESP_OK(pcnt_unit_add_watch_step(unit, -25));
|
||||||
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, pcnt_unit_add_watch_step(unit, -120));
|
||||||
|
TEST_ESP_OK(pcnt_unit_add_watch_step(unit, 20));
|
||||||
|
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));
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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, 25); // 0+25*4 = 100 -> 0
|
||||||
|
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(0, count_value);
|
||||||
|
TEST_ASSERT_EQUAL(6, user_data.index);
|
||||||
|
TEST_ASSERT_EQUAL(11, user_data.triggered_watch_values[0]); // watch point
|
||||||
|
TEST_ASSERT_EQUAL(20, user_data.triggered_watch_values[1]); // step point (20*1)
|
||||||
|
TEST_ASSERT_EQUAL(40, user_data.triggered_watch_values[2]); // step point (20*2)
|
||||||
|
TEST_ASSERT_EQUAL(60, user_data.triggered_watch_values[3]); // step point (40+20*2)
|
||||||
|
TEST_ASSERT_EQUAL(80, user_data.triggered_watch_values[4]); // step point (60+20*2)
|
||||||
|
TEST_ASSERT_EQUAL(0, user_data.triggered_watch_values[5]); // watch point (overflow zero cross)
|
||||||
|
|
||||||
|
printf("change step interval\r\n");
|
||||||
|
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, pcnt_unit_remove_watch_step(unit, -20)); // -20 is not a step point
|
||||||
|
TEST_ESP_OK(pcnt_unit_remove_watch_step(unit, -25));
|
||||||
|
TEST_ESP_OK(pcnt_unit_add_watch_step(unit, -20));
|
||||||
|
|
||||||
|
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); // 20*(-4) = -80
|
||||||
|
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(-80, count_value);
|
||||||
|
TEST_ASSERT_EQUAL(5, user_data.index);
|
||||||
|
TEST_ASSERT_EQUAL(-20, user_data.triggered_watch_values[0]); // step point (-20*1)
|
||||||
|
TEST_ASSERT_EQUAL(-40, user_data.triggered_watch_values[1]); // step point (-20*2)
|
||||||
|
TEST_ASSERT_EQUAL(-50, user_data.triggered_watch_values[2]); // watch point
|
||||||
|
TEST_ASSERT_EQUAL(-60, user_data.triggered_watch_values[3]); // step point (-20*3)
|
||||||
|
TEST_ASSERT_EQUAL(-80, user_data.triggered_watch_values[4]); // step point (-20*4)
|
||||||
|
|
||||||
|
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 //PCNT_LL_STEP_NOTIFY_DIR_LIMIT
|
||||||
#endif // SOC_PCNT_SUPPORT_STEP_NOTIFY
|
#endif // SOC_PCNT_SUPPORT_STEP_NOTIFY
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -34,11 +34,10 @@ typedef enum {
|
|||||||
} pcnt_ll_watch_event_id_t;
|
} pcnt_ll_watch_event_id_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PCNT_LL_STEP_EVENT_REACH_LIMIT = PCNT_LL_WATCH_EVENT_MAX,
|
PCNT_LL_STEP_EVENT_REACH_INTERVAL_FORWARD = PCNT_LL_WATCH_EVENT_MAX,
|
||||||
PCNT_LL_STEP_EVENT_REACH_INTERVAL
|
PCNT_LL_STEP_EVENT_REACH_INTERVAL_BACKWARD,
|
||||||
} pcnt_ll_step_event_id_t;
|
} 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_WATCH_EVENT_MASK ((1 << PCNT_LL_WATCH_EVENT_MAX) - 1)
|
||||||
#define PCNT_LL_UNIT_WATCH_EVENT(unit_id) (1 << (unit_id))
|
#define PCNT_LL_UNIT_WATCH_EVENT(unit_id) (1 << (unit_id))
|
||||||
|
|
||||||
@@ -157,23 +156,16 @@ static inline void pcnt_ll_enable_step_notify(pcnt_dev_t *hw, uint32_t unit, boo
|
|||||||
*
|
*
|
||||||
* @param hw Peripheral PCNT hardware instance address.
|
* @param hw Peripheral PCNT hardware instance address.
|
||||||
* @param unit PCNT unit number
|
* @param unit PCNT unit number
|
||||||
|
* @param direction PCNT step direction
|
||||||
* @param value PCNT step value
|
* @param value PCNT step value
|
||||||
*/
|
*/
|
||||||
static inline void pcnt_ll_set_step_value(pcnt_dev_t *hw, uint32_t unit, int value)
|
static inline void pcnt_ll_set_step_value(pcnt_dev_t *hw, uint32_t unit, pcnt_step_direction_t direction, uint16_t value)
|
||||||
{
|
{
|
||||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->change_conf_unit[3 - unit], cnt_step, 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 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -167,10 +167,12 @@ static inline void pcnt_ll_enable_step_notify(pcnt_dev_t *hw, uint32_t unit, boo
|
|||||||
*
|
*
|
||||||
* @param hw Peripheral PCNT hardware instance address.
|
* @param hw Peripheral PCNT hardware instance address.
|
||||||
* @param unit PCNT unit number
|
* @param unit PCNT unit number
|
||||||
|
* @param direction PCNT step direction
|
||||||
* @param value PCNT step value
|
* @param value PCNT step value
|
||||||
*/
|
*/
|
||||||
static inline void pcnt_ll_set_step_value(pcnt_dev_t *hw, uint32_t unit, int value)
|
static inline void pcnt_ll_set_step_value(pcnt_dev_t *hw, uint32_t unit, pcnt_step_direction_t direction, int value)
|
||||||
{
|
{
|
||||||
|
(void)direction;
|
||||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->change_conf_unit[3 - unit], cnt_step, value);
|
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->change_conf_unit[3 - unit], cnt_step, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -159,10 +159,12 @@ static inline void pcnt_ll_enable_step_notify(pcnt_dev_t *hw, uint32_t unit, boo
|
|||||||
*
|
*
|
||||||
* @param hw Peripheral PCNT hardware instance address.
|
* @param hw Peripheral PCNT hardware instance address.
|
||||||
* @param unit PCNT unit number
|
* @param unit PCNT unit number
|
||||||
|
* @param direction PCNT step direction
|
||||||
* @param value PCNT step value
|
* @param value PCNT step value
|
||||||
*/
|
*/
|
||||||
static inline void pcnt_ll_set_step_value(pcnt_dev_t *hw, uint32_t unit, int value)
|
static inline void pcnt_ll_set_step_value(pcnt_dev_t *hw, uint32_t unit, pcnt_step_direction_t direction, int value)
|
||||||
{
|
{
|
||||||
|
(void)direction;
|
||||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->change_conf_unit[3 - unit], cnt_step, value);
|
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->change_conf_unit[3 - unit], cnt_step, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -39,6 +39,14 @@ typedef enum {
|
|||||||
PCNT_UNIT_ZERO_CROSS_INVALID, /*!< invalid zero cross mode */
|
PCNT_UNIT_ZERO_CROSS_INVALID, /*!< invalid zero cross mode */
|
||||||
} pcnt_unit_zero_cross_mode_t;
|
} pcnt_unit_zero_cross_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PCNT step direction
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
PCNT_STEP_FORWARD, /*!< step forward, e.g., [N]->[N+1]->[N+2]->... */
|
||||||
|
PCNT_STEP_BACKWARD, /*!< step backward, e.g., [N]->[N-1]->[N-2]->... */
|
||||||
|
} pcnt_step_direction_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -12,14 +12,14 @@ extern "C" {
|
|||||||
|
|
||||||
/** Group: Configuration Register */
|
/** Group: Configuration Register */
|
||||||
/** Type of un_conf0 register
|
/** Type of un_conf0 register
|
||||||
* Configuration register 0 for unit 0
|
* Configuration register 0 for unit n
|
||||||
*/
|
*/
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
/** filter_thres_un : R/W; bitpos: [9:0]; default: 16;
|
/** filter_thres_un : R/W; bitpos: [9:0]; default: 16;
|
||||||
* Configures the maximum threshold for the filter. Any pulses with width less than
|
* Configures the maximum threshold for the filter. Any pulses with width less than
|
||||||
* this will be ignored when the filter is enabled. \\
|
* this will be ignored when the filter is enabled.
|
||||||
* Measurement unit: APB_CLK cycles.\\
|
* Measurement unit: APB_CLK cycles.
|
||||||
*/
|
*/
|
||||||
uint32_t filter_thres_un:10;
|
uint32_t filter_thres_un:10;
|
||||||
/** filter_en_un : R/W; bitpos: [10]; default: 1;
|
/** filter_en_un : R/W; bitpos: [10]; default: 1;
|
||||||
@@ -49,67 +49,63 @@ typedef union {
|
|||||||
*/
|
*/
|
||||||
uint32_t thr_thres1_en_un:1;
|
uint32_t thr_thres1_en_un:1;
|
||||||
/** ch0_neg_mode_un : R/W; bitpos: [17:16]; default: 0;
|
/** ch0_neg_mode_un : R/W; bitpos: [17:16]; default: 0;
|
||||||
* Configures the behavior when the signal input of channel 0 detects a negative
|
* Configures the behavior when the signal input of channel 0 detects a negative edge.
|
||||||
* edge.\\
|
* 1: Increment the counter
|
||||||
* 1: Increment the counter\\
|
* 2: Decrement the counter
|
||||||
* 2: Decrement the counter\\
|
* 0, 3: No effect
|
||||||
* 0, 3: No effect \\
|
|
||||||
*/
|
*/
|
||||||
uint32_t ch0_neg_mode_un:2;
|
uint32_t ch0_neg_mode_un:2;
|
||||||
/** ch0_pos_mode_un : R/W; bitpos: [19:18]; default: 0;
|
/** ch0_pos_mode_un : R/W; bitpos: [19:18]; default: 0;
|
||||||
* Configures the behavior when the signal input of channel 0 detects a positive edge.
|
* Configures the behavior when the signal input of channel 0 detects a positive edge.
|
||||||
* \\
|
* 1: Increment the counter
|
||||||
* 1: Increment the counter\\
|
* 2: Decrement the counter
|
||||||
* 2: Decrement the counter\\
|
* 0, 3: No effect
|
||||||
* 0, 3: No effect \\
|
|
||||||
*/
|
*/
|
||||||
uint32_t ch0_pos_mode_un:2;
|
uint32_t ch0_pos_mode_un:2;
|
||||||
/** ch0_hctrl_mode_un : R/W; bitpos: [21:20]; default: 0;
|
/** ch0_hctrl_mode_un : R/W; bitpos: [21:20]; default: 0;
|
||||||
* Configures how the CHn_POS_MODE/CHn_NEG_MODE settings will be modified when the
|
* Configures how the CHn_POS_MODE/CHn_NEG_MODE settings will be modified when the
|
||||||
* control signal is high. \\
|
* control signal is high.
|
||||||
* 0: No modification\\
|
* 0: No modification
|
||||||
* 1: Invert behavior (increase -> decrease, decrease -> increase)\\
|
* 1: Invert behavior (increase -> decrease, decrease -> increase)
|
||||||
* 2, 3: Inhibit counter modification \\
|
* 2, 3: Inhibit counter modification
|
||||||
*/
|
*/
|
||||||
uint32_t ch0_hctrl_mode_un:2;
|
uint32_t ch0_hctrl_mode_un:2;
|
||||||
/** ch0_lctrl_mode_un : R/W; bitpos: [23:22]; default: 0;
|
/** ch0_lctrl_mode_un : R/W; bitpos: [23:22]; default: 0;
|
||||||
* Configures how the CHn_POS_MODE/CHn_NEG_MODE settings will be modified when the
|
* Configures how the CHn_POS_MODE/CHn_NEG_MODE settings will be modified when the
|
||||||
* control signal is low. \\
|
* control signal is low.
|
||||||
* 0: No modification\\
|
* 0: No modification
|
||||||
* 1: Invert behavior (increase -> decrease, decrease -> increase)\\
|
* 1: Invert behavior (increase -> decrease, decrease -> increase)
|
||||||
* 2, 3: Inhibit counter modification\\
|
* 2, 3: Inhibit counter modification
|
||||||
*/
|
*/
|
||||||
uint32_t ch0_lctrl_mode_un:2;
|
uint32_t ch0_lctrl_mode_un:2;
|
||||||
/** ch1_neg_mode_un : R/W; bitpos: [25:24]; default: 0;
|
/** ch1_neg_mode_un : R/W; bitpos: [25:24]; default: 0;
|
||||||
* Configures the behavior when the signal input of channel 1 detects a negative edge.
|
* Configures the behavior when the signal input of channel 1 detects a negative edge.
|
||||||
* \\
|
* 1: Increment the counter
|
||||||
* 1: Increment the counter\\
|
* 2: Decrement the counter
|
||||||
* 2: Decrement the counter\\
|
* 0, 3: No effect
|
||||||
* 0, 3: No effect \\
|
|
||||||
*/
|
*/
|
||||||
uint32_t ch1_neg_mode_un:2;
|
uint32_t ch1_neg_mode_un:2;
|
||||||
/** ch1_pos_mode_un : R/W; bitpos: [27:26]; default: 0;
|
/** ch1_pos_mode_un : R/W; bitpos: [27:26]; default: 0;
|
||||||
* Configures the behavior when the signal input of channel 1 detects a positive edge.
|
* Configures the behavior when the signal input of channel 1 detects a positive edge.
|
||||||
* \\
|
* 1: Increment the counter
|
||||||
* 1: Increment the counter\\
|
* 2: Decrement the counter
|
||||||
* 2: Decrement the counter\\
|
* 0, 3: No effect
|
||||||
* 0, 3: No effect \\
|
|
||||||
*/
|
*/
|
||||||
uint32_t ch1_pos_mode_un:2;
|
uint32_t ch1_pos_mode_un:2;
|
||||||
/** ch1_hctrl_mode_un : R/W; bitpos: [29:28]; default: 0;
|
/** ch1_hctrl_mode_un : R/W; bitpos: [29:28]; default: 0;
|
||||||
* Configures how the CHn_POS_MODE/CHn_NEG_MODE settings will be modified when the
|
* Configures how the CHn_POS_MODE/CHn_NEG_MODE settings will be modified when the
|
||||||
* control signal is high. \\
|
* control signal is high.
|
||||||
* 0: No modification\\
|
* 0: No modification
|
||||||
* 1: Invert behavior (increase -> decrease, decrease -> increase)\\
|
* 1: Invert behavior (increase -> decrease, decrease -> increase)
|
||||||
* 2, 3: Inhibit counter modification \\
|
* 2, 3: Inhibit counter modification
|
||||||
*/
|
*/
|
||||||
uint32_t ch1_hctrl_mode_un:2;
|
uint32_t ch1_hctrl_mode_un:2;
|
||||||
/** ch1_lctrl_mode_un : R/W; bitpos: [31:30]; default: 0;
|
/** ch1_lctrl_mode_un : R/W; bitpos: [31:30]; default: 0;
|
||||||
* Configures how the CHn_POS_MODE/CHn_NEG_MODE settings will be modified when the
|
* Configures how the CHn_POS_MODE/CHn_NEG_MODE settings will be modified when the
|
||||||
* control signal is low. \\
|
* control signal is low.
|
||||||
* 0: No modification\\
|
* 0: No modification
|
||||||
* 1: Invert behavior (increase -> decrease, decrease -> increase)\\
|
* 1: Invert behavior (increase -> decrease, decrease -> increase)
|
||||||
* 2, 3: Inhibit counter modification \\
|
* 2, 3: Inhibit counter modification
|
||||||
*/
|
*/
|
||||||
uint32_t ch1_lctrl_mode_un:2;
|
uint32_t ch1_lctrl_mode_un:2;
|
||||||
};
|
};
|
||||||
@@ -117,7 +113,7 @@ typedef union {
|
|||||||
} pcnt_un_conf0_reg_t;
|
} pcnt_un_conf0_reg_t;
|
||||||
|
|
||||||
/** Type of un_conf1 register
|
/** Type of un_conf1 register
|
||||||
* Configuration register 1 for unit 0
|
* Configuration register 1 for unit n
|
||||||
*/
|
*/
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
@@ -134,7 +130,7 @@ typedef union {
|
|||||||
} pcnt_un_conf1_reg_t;
|
} pcnt_un_conf1_reg_t;
|
||||||
|
|
||||||
/** Type of un_conf2 register
|
/** Type of un_conf2 register
|
||||||
* Configuration register 2 for unit 0
|
* Configuration register 2 for unit n
|
||||||
*/
|
*/
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
@@ -152,6 +148,24 @@ typedef union {
|
|||||||
uint32_t val;
|
uint32_t val;
|
||||||
} pcnt_un_conf2_reg_t;
|
} pcnt_un_conf2_reg_t;
|
||||||
|
|
||||||
|
/** Type of un_conf3 register
|
||||||
|
* Configuration register for unit n's step value.
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
/** cnt_h_step_un : R/W; bitpos: [15:0]; default: 0;
|
||||||
|
* Configures the forward rotation step value for unit n.
|
||||||
|
*/
|
||||||
|
uint32_t cnt_h_step_un:16;
|
||||||
|
/** cnt_l_step_un : R/W; bitpos: [31:16]; default: 0;
|
||||||
|
* Configures the reverse rotation step value for unit n.
|
||||||
|
*/
|
||||||
|
uint32_t cnt_l_step_un:16;
|
||||||
|
};
|
||||||
|
uint32_t val;
|
||||||
|
} pcnt_un_conf3_reg_t;
|
||||||
|
|
||||||
|
|
||||||
/** Type of ctrl register
|
/** Type of ctrl register
|
||||||
* Control register for all counters
|
* Control register for all counters
|
||||||
*/
|
*/
|
||||||
@@ -217,26 +231,10 @@ typedef union {
|
|||||||
uint32_t val;
|
uint32_t val;
|
||||||
} pcnt_ctrl_reg_t;
|
} pcnt_ctrl_reg_t;
|
||||||
|
|
||||||
/** Type of un_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_u3 : 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 */
|
/** Group: Status Register */
|
||||||
/** Type of un_cnt register
|
/** Type of un_cnt register
|
||||||
* Counter value for unit 0
|
* Counter value for unit n
|
||||||
*/
|
*/
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
@@ -250,65 +248,65 @@ typedef union {
|
|||||||
} pcnt_un_cnt_reg_t;
|
} pcnt_un_cnt_reg_t;
|
||||||
|
|
||||||
/** Type of un_status register
|
/** Type of un_status register
|
||||||
* PNCT UNIT0 status register
|
* PNCT UNITn status register
|
||||||
*/
|
*/
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
/** cnt_thr_zero_mode_un : RO; bitpos: [1:0]; default: 0;
|
/** cnt_thr_zero_mode_un : RO; bitpos: [1:0]; default: 0;
|
||||||
* Represents the pulse counter status of PCNT_Un corresponding to 0. \\
|
* Represents the pulse counter status of PCNT_Un corresponding to 0.
|
||||||
* 0: pulse counter decreases from positive to 0\\
|
* 0: pulse counter decreases from positive to 0
|
||||||
* 1: pulse counter increases from negative to 0\\
|
* 1: pulse counter increases from negative to 0
|
||||||
* 2: pulse counter is negative\\
|
* 2: pulse counter is negative
|
||||||
* 3: pulse counter is positive \\
|
* 3: pulse counter is positive
|
||||||
*/
|
*/
|
||||||
uint32_t cnt_thr_zero_mode_un:2;
|
uint32_t cnt_thr_zero_mode_un:2;
|
||||||
/** cnt_thr_thres1_lat_un : RO; bitpos: [2]; default: 0;
|
/** cnt_thr_thres1_lat_un : RO; bitpos: [2]; default: 0;
|
||||||
* Represents the latched value of thres1 event of PCNT_Un when threshold event
|
* Represents the latched value of thres1 event of PCNT_Un when threshold event
|
||||||
* interrupt is valid. \\
|
* interrupt is valid.
|
||||||
* 0: others\\
|
* 0: others
|
||||||
* 1: the current pulse counter equals to thres1 and thres1 event is valid \\
|
* 1: the current pulse counter equals to thres1 and thres1 event is valid
|
||||||
*/
|
*/
|
||||||
uint32_t cnt_thr_thres1_lat_un:1;
|
uint32_t cnt_thr_thres1_lat_un:1;
|
||||||
/** cnt_thr_thres0_lat_un : RO; bitpos: [3]; default: 0;
|
/** cnt_thr_thres0_lat_un : RO; bitpos: [3]; default: 0;
|
||||||
* Represents the latched value of thres0 event of PCNT_Un when threshold event
|
* Represents the latched value of thres0 event of PCNT_Un when threshold event
|
||||||
* interrupt is valid. \\
|
* interrupt is valid.
|
||||||
* 0: others\\
|
* 0: others
|
||||||
* 1: the current pulse counter equals to thres0 and thres0 event is valid \\
|
* 1: the current pulse counter equals to thres0 and thres0 event is valid
|
||||||
*/
|
*/
|
||||||
uint32_t cnt_thr_thres0_lat_un:1;
|
uint32_t cnt_thr_thres0_lat_un:1;
|
||||||
/** cnt_thr_l_lim_lat_un : RO; bitpos: [4]; default: 0;
|
/** cnt_thr_l_lim_lat_un : RO; bitpos: [4]; default: 0;
|
||||||
* Represents the latched value of low limit event of PCNT_Un when threshold event
|
* Represents the latched value of low limit event of PCNT_Un when threshold event
|
||||||
* interrupt is valid. \\
|
* interrupt is valid.
|
||||||
* 0: others\\
|
* 0: others
|
||||||
* 1: the current pulse counter equals to thr_l_lim and low limit event is valid. \\
|
* 1: the current pulse counter equals to thr_l_lim and low limit event is valid.
|
||||||
*/
|
*/
|
||||||
uint32_t cnt_thr_l_lim_lat_un:1;
|
uint32_t cnt_thr_l_lim_lat_un:1;
|
||||||
/** cnt_thr_h_lim_lat_un : RO; bitpos: [5]; default: 0;
|
/** cnt_thr_h_lim_lat_un : RO; bitpos: [5]; default: 0;
|
||||||
* Represents the latched value of high limit event of PCNT_Un when threshold event
|
* Represents the latched value of high limit event of PCNT_Un when threshold event
|
||||||
* interrupt is valid. \\
|
* interrupt is valid.
|
||||||
* 0: others\\
|
* 0: others
|
||||||
* 1: the current pulse counter equals to thr_h_lim and high limit event is valid. \\
|
* 1: the current pulse counter equals to thr_h_lim and high limit event is valid.
|
||||||
*/
|
*/
|
||||||
uint32_t cnt_thr_h_lim_lat_un:1;
|
uint32_t cnt_thr_h_lim_lat_un:1;
|
||||||
/** cnt_thr_zero_lat_un : RO; bitpos: [6]; default: 0;
|
/** cnt_thr_zero_lat_un : RO; bitpos: [6]; default: 0;
|
||||||
* Represents the latched value of zero threshold event of PCNT_Un when threshold
|
* Represents the latched value of zero threshold event of PCNT_Un when threshold
|
||||||
* event interrupt is valid. \\
|
* event interrupt is valid.
|
||||||
* 0: others\\
|
* 0: others
|
||||||
* 1: the current pulse counter equals to 0 and zero threshold event is valid. \\
|
* 1: the current pulse counter equals to 0 and zero threshold event is valid.
|
||||||
*/
|
*/
|
||||||
uint32_t cnt_thr_zero_lat_un:1;
|
uint32_t cnt_thr_zero_lat_un:1;
|
||||||
/** cnt_thr_step_lim_lat_un : RO; bitpos: [7]; default: 0;
|
/** cnt_thr_h_step_lat_un : RO; bitpos: [7]; default: 0;
|
||||||
* The latched value of step counter limit event of PCNT_Un when step counter event
|
* Represents the latched value of step counter event of PCNT_Un when step counter
|
||||||
* interrupt is valid. 1: the current pulse counter equals to reg_cnt_step_lim and
|
* event interrupt is valid. 1: the current pulse counter decrement equals to
|
||||||
* step counter event is valid. 0: others
|
* reg_cnt_step and step counter event is valid. 0: others
|
||||||
*/
|
*/
|
||||||
uint32_t cnt_thr_step_lim_lat_un:1;
|
uint32_t cnt_thr_h_step_lat_un:1;
|
||||||
/** cnt_thr_step_lat_un : RO; bitpos: [8]; default: 0;
|
/** cnt_thr_l_step_lat_un : RO; bitpos: [8]; default: 0;
|
||||||
* The latched value of step counter event of PCNT_Un when step counter event
|
* Represents the latched value of step counter event of PCNT_Un when step counter
|
||||||
* interrupt is valid. 1: the current pulse counter increment equals to reg_cnt_step
|
* event interrupt is valid. 1: the current pulse counter increment equals to
|
||||||
* and step counter event is valid. 0: others
|
* reg_cnt_step and step counter event is valid. 0: others
|
||||||
*/
|
*/
|
||||||
uint32_t cnt_thr_step_lat_un:1;
|
uint32_t cnt_thr_l_step_lat_un:1;
|
||||||
uint32_t reserved_9:23;
|
uint32_t reserved_9:23;
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
@@ -427,7 +425,7 @@ typedef union {
|
|||||||
*/
|
*/
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
/** date : R/W; bitpos: [31:0]; default: 36765968;
|
/** date : R/W; bitpos: [31:0]; default: 37778192;
|
||||||
* Version control register.
|
* Version control register.
|
||||||
*/
|
*/
|
||||||
uint32_t date:32;
|
uint32_t date:32;
|
||||||
@@ -441,6 +439,7 @@ typedef struct pcnt_dev_t {
|
|||||||
pcnt_un_conf0_reg_t conf0;
|
pcnt_un_conf0_reg_t conf0;
|
||||||
pcnt_un_conf1_reg_t conf1;
|
pcnt_un_conf1_reg_t conf1;
|
||||||
pcnt_un_conf2_reg_t conf2;
|
pcnt_un_conf2_reg_t conf2;
|
||||||
|
pcnt_un_conf3_reg_t conf3;
|
||||||
} conf_unit[4];
|
} conf_unit[4];
|
||||||
volatile pcnt_un_cnt_reg_t cnt_unit[4];
|
volatile pcnt_un_cnt_reg_t cnt_unit[4];
|
||||||
volatile pcnt_int_raw_reg_t int_raw;
|
volatile pcnt_int_raw_reg_t int_raw;
|
||||||
@@ -449,7 +448,6 @@ typedef struct pcnt_dev_t {
|
|||||||
volatile pcnt_int_clr_reg_t int_clr;
|
volatile pcnt_int_clr_reg_t int_clr;
|
||||||
volatile pcnt_un_status_reg_t status_unit[4];
|
volatile pcnt_un_status_reg_t status_unit[4];
|
||||||
volatile pcnt_ctrl_reg_t ctrl;
|
volatile pcnt_ctrl_reg_t ctrl;
|
||||||
volatile pcnt_un_change_conf_reg_t change_conf_unit[4]; // Note the unit order is 3210
|
|
||||||
uint32_t reserved_074[34];
|
uint32_t reserved_074[34];
|
||||||
volatile pcnt_date_reg_t date;
|
volatile pcnt_date_reg_t date;
|
||||||
} pcnt_dev_t;
|
} pcnt_dev_t;
|
||||||
|
@@ -1,523 +0,0 @@
|
|||||||
/**
|
|
||||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Group: Configuration Register */
|
|
||||||
/** Type of un_conf0 register
|
|
||||||
* Configuration register 0 for unit n
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
/** filter_thres_un : R/W; bitpos: [9:0]; default: 16;
|
|
||||||
* Configures the maximum threshold for the filter. Any pulses with width less than
|
|
||||||
* this will be ignored when the filter is enabled.
|
|
||||||
* Measurement unit: APB_CLK cycles.
|
|
||||||
*/
|
|
||||||
uint32_t filter_thres_un:10;
|
|
||||||
/** filter_en_un : R/W; bitpos: [10]; default: 1;
|
|
||||||
* This is the enable bit for unit n's input filter.
|
|
||||||
*/
|
|
||||||
uint32_t filter_en_un:1;
|
|
||||||
/** thr_zero_en_un : R/W; bitpos: [11]; default: 1;
|
|
||||||
* This is the enable bit for unit n's zero comparator.
|
|
||||||
*/
|
|
||||||
uint32_t thr_zero_en_un:1;
|
|
||||||
/** thr_h_lim_en_un : R/W; bitpos: [12]; default: 1;
|
|
||||||
* This is the enable bit for unit n's thr_h_lim comparator. Configures it to enable
|
|
||||||
* the high limit interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t thr_h_lim_en_un:1;
|
|
||||||
/** thr_l_lim_en_un : R/W; bitpos: [13]; default: 1;
|
|
||||||
* This is the enable bit for unit n's thr_l_lim comparator. Configures it to enable
|
|
||||||
* the low limit interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t thr_l_lim_en_un:1;
|
|
||||||
/** thr_thres0_en_un : R/W; bitpos: [14]; default: 0;
|
|
||||||
* This is the enable bit for unit n's thres0 comparator.
|
|
||||||
*/
|
|
||||||
uint32_t thr_thres0_en_un:1;
|
|
||||||
/** thr_thres1_en_un : R/W; bitpos: [15]; default: 0;
|
|
||||||
* This is the enable bit for unit n's thres1 comparator.
|
|
||||||
*/
|
|
||||||
uint32_t thr_thres1_en_un:1;
|
|
||||||
/** ch0_neg_mode_un : R/W; bitpos: [17:16]; default: 0;
|
|
||||||
* Configures the behavior when the signal input of channel 0 detects a negative edge.
|
|
||||||
* 1: Increment the counter
|
|
||||||
* 2: Decrement the counter
|
|
||||||
* 0, 3: No effect
|
|
||||||
*/
|
|
||||||
uint32_t ch0_neg_mode_un:2;
|
|
||||||
/** ch0_pos_mode_un : R/W; bitpos: [19:18]; default: 0;
|
|
||||||
* Configures the behavior when the signal input of channel 0 detects a positive edge.
|
|
||||||
* 1: Increment the counter
|
|
||||||
* 2: Decrement the counter
|
|
||||||
* 0, 3: No effect
|
|
||||||
*/
|
|
||||||
uint32_t ch0_pos_mode_un:2;
|
|
||||||
/** ch0_hctrl_mode_un : R/W; bitpos: [21:20]; default: 0;
|
|
||||||
* Configures how the CHn_POS_MODE/CHn_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
|
|
||||||
*/
|
|
||||||
uint32_t ch0_hctrl_mode_un:2;
|
|
||||||
/** ch0_lctrl_mode_un : R/W; bitpos: [23:22]; default: 0;
|
|
||||||
* Configures how the CHn_POS_MODE/CHn_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
|
|
||||||
*/
|
|
||||||
uint32_t ch0_lctrl_mode_un:2;
|
|
||||||
/** ch1_neg_mode_un : R/W; bitpos: [25:24]; default: 0;
|
|
||||||
* Configures 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
|
|
||||||
*/
|
|
||||||
uint32_t ch1_neg_mode_un:2;
|
|
||||||
/** ch1_pos_mode_un : R/W; bitpos: [27:26]; default: 0;
|
|
||||||
* Configures 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
|
|
||||||
*/
|
|
||||||
uint32_t ch1_pos_mode_un:2;
|
|
||||||
/** ch1_hctrl_mode_un : R/W; bitpos: [29:28]; default: 0;
|
|
||||||
* Configures how the CHn_POS_MODE/CHn_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
|
|
||||||
*/
|
|
||||||
uint32_t ch1_hctrl_mode_un:2;
|
|
||||||
/** ch1_lctrl_mode_un : R/W; bitpos: [31:30]; default: 0;
|
|
||||||
* Configures how the CHn_POS_MODE/CHn_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
|
|
||||||
*/
|
|
||||||
uint32_t ch1_lctrl_mode_un:2;
|
|
||||||
};
|
|
||||||
uint32_t val;
|
|
||||||
} pcnt_un_conf0_reg_t;
|
|
||||||
|
|
||||||
/** Type of un_conf1 register
|
|
||||||
* Configuration register 1 for unit n
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
/** cnt_thres0_un : R/W; bitpos: [15:0]; default: 0;
|
|
||||||
* Configures the thres0 value for unit n.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thres0_un:16;
|
|
||||||
/** cnt_thres1_un : R/W; bitpos: [31:16]; default: 0;
|
|
||||||
* Configures the thres1 value for unit n.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thres1_un:16;
|
|
||||||
};
|
|
||||||
uint32_t val;
|
|
||||||
} pcnt_un_conf1_reg_t;
|
|
||||||
|
|
||||||
/** Type of un_conf2 register
|
|
||||||
* Configuration register 2 for unit n
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
/** cnt_h_lim_un : R/W; bitpos: [15:0]; default: 0;
|
|
||||||
* Configures the thr_h_lim value for unit n. When pulse_cnt reaches this value, the
|
|
||||||
* counter will be cleared to 0.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_h_lim_un:16;
|
|
||||||
/** cnt_l_lim_un : R/W; bitpos: [31:16]; default: 0;
|
|
||||||
* Configures the thr_l_lim value for unit n. When pulse_cnt reaches this value, the
|
|
||||||
* counter will be cleared to 0.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_l_lim_un:16;
|
|
||||||
};
|
|
||||||
uint32_t val;
|
|
||||||
} pcnt_un_conf2_reg_t;
|
|
||||||
|
|
||||||
/** Type of u0_conf3 register
|
|
||||||
* Configuration register for unit $n's step value.
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
/** 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;
|
|
||||||
/** 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 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;
|
|
||||||
|
|
||||||
/** Type of ctrl register
|
|
||||||
* Control register for all counters
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
/** pulse_cnt_rst_u0 : R/W; bitpos: [0]; default: 1;
|
|
||||||
* Set this bit to clear unit 0's counter.
|
|
||||||
*/
|
|
||||||
uint32_t pulse_cnt_rst_u0:1;
|
|
||||||
/** cnt_pause_u0 : R/W; bitpos: [1]; default: 0;
|
|
||||||
* Set this bit to freeze unit 0's counter.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_pause_u0:1;
|
|
||||||
/** pulse_cnt_rst_u1 : R/W; bitpos: [2]; default: 1;
|
|
||||||
* Set this bit to clear unit 1's counter.
|
|
||||||
*/
|
|
||||||
uint32_t pulse_cnt_rst_u1:1;
|
|
||||||
/** cnt_pause_u1 : R/W; bitpos: [3]; default: 0;
|
|
||||||
* Set this bit to freeze unit 1's counter.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_pause_u1:1;
|
|
||||||
/** pulse_cnt_rst_u2 : R/W; bitpos: [4]; default: 1;
|
|
||||||
* Set this bit to clear unit 2's counter.
|
|
||||||
*/
|
|
||||||
uint32_t pulse_cnt_rst_u2:1;
|
|
||||||
/** cnt_pause_u2 : R/W; bitpos: [5]; default: 0;
|
|
||||||
* Set this bit to freeze unit 2's counter.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_pause_u2:1;
|
|
||||||
/** pulse_cnt_rst_u3 : R/W; bitpos: [6]; default: 1;
|
|
||||||
* Set this bit to clear unit 3's counter.
|
|
||||||
*/
|
|
||||||
uint32_t pulse_cnt_rst_u3:1;
|
|
||||||
/** cnt_pause_u3 : R/W; bitpos: [7]; default: 0;
|
|
||||||
* Set this bit to freeze unit 3's counter.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_pause_u3:1;
|
|
||||||
/** 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
|
|
||||||
* application
|
|
||||||
*/
|
|
||||||
uint32_t clk_en:1;
|
|
||||||
uint32_t reserved_17:15;
|
|
||||||
};
|
|
||||||
uint32_t val;
|
|
||||||
} pcnt_ctrl_reg_t;
|
|
||||||
|
|
||||||
|
|
||||||
/** Group: Status Register */
|
|
||||||
/** Type of un_cnt register
|
|
||||||
* Counter value for unit n
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
/** pulse_cnt_un : RO; bitpos: [15:0]; default: 0;
|
|
||||||
* Represents the current pulse count value for unit n.
|
|
||||||
*/
|
|
||||||
uint32_t pulse_cnt_un:16;
|
|
||||||
uint32_t reserved_16:16;
|
|
||||||
};
|
|
||||||
uint32_t val;
|
|
||||||
} pcnt_un_cnt_reg_t;
|
|
||||||
|
|
||||||
/** Type of un_status register
|
|
||||||
* PNCT UNITn status register
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
/** cnt_thr_zero_mode_un : RO; bitpos: [1:0]; default: 0;
|
|
||||||
* Represents the pulse counter status of PCNT_Un corresponding to 0.
|
|
||||||
* 0: pulse counter decreases from positive to 0
|
|
||||||
* 1: pulse counter increases from negative to 0
|
|
||||||
* 2: pulse counter is negative
|
|
||||||
* 3: pulse counter is positive
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_zero_mode_un:2;
|
|
||||||
/** cnt_thr_thres1_lat_un : RO; bitpos: [2]; default: 0;
|
|
||||||
* Represents the latched value of thres1 event of PCNT_Un when threshold event
|
|
||||||
* interrupt is valid.
|
|
||||||
* 0: others
|
|
||||||
* 1: the current pulse counter equals to thres1 and thres1 event is valid
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_thres1_lat_un:1;
|
|
||||||
/** cnt_thr_thres0_lat_un : RO; bitpos: [3]; default: 0;
|
|
||||||
* Represents the latched value of thres0 event of PCNT_Un when threshold event
|
|
||||||
* interrupt is valid.
|
|
||||||
* 0: others
|
|
||||||
* 1: the current pulse counter equals to thres0 and thres0 event is valid
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_thres0_lat_un:1;
|
|
||||||
/** cnt_thr_l_lim_lat_un : RO; bitpos: [4]; default: 0;
|
|
||||||
* Represents the latched value of low limit event of PCNT_Un when threshold event
|
|
||||||
* interrupt is valid.
|
|
||||||
* 0: others
|
|
||||||
* 1: the current pulse counter equals to thr_l_lim and low limit event is valid.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_l_lim_lat_un:1;
|
|
||||||
/** cnt_thr_h_lim_lat_un : RO; bitpos: [5]; default: 0;
|
|
||||||
* Represents the latched value of high limit event of PCNT_Un when threshold event
|
|
||||||
* interrupt is valid.
|
|
||||||
* 0: others
|
|
||||||
* 1: the current pulse counter equals to thr_h_lim and high limit event is valid.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_h_lim_lat_un:1;
|
|
||||||
/** cnt_thr_zero_lat_un : RO; bitpos: [6]; default: 0;
|
|
||||||
* Represents the latched value of zero threshold event of PCNT_Un when threshold
|
|
||||||
* event interrupt is valid.
|
|
||||||
* 0: others
|
|
||||||
* 1: the current pulse counter equals to 0 and zero threshold event is valid.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_zero_lat_un:1;
|
|
||||||
/** cnt_thr_h_step_lat_un : RO; bitpos: [7]; default: 0;
|
|
||||||
* Represents the latched value of step counter event of PCNT_Un when step counter
|
|
||||||
* event interrupt is valid. 1: the current pulse counter decrement equals to
|
|
||||||
* reg_cnt_step and step counter event is valid. 0: others
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_h_step_lat_un:1;
|
|
||||||
/** cnt_thr_l_step_lat_un : RO; bitpos: [8]; default: 0;
|
|
||||||
* Represents 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_l_step_lat_un:1;
|
|
||||||
uint32_t reserved_9:23;
|
|
||||||
};
|
|
||||||
uint32_t val;
|
|
||||||
} pcnt_un_status_reg_t;
|
|
||||||
|
|
||||||
|
|
||||||
/** Group: Interrupt Register */
|
|
||||||
/** Type of int_raw register
|
|
||||||
* Interrupt raw status register
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
/** cnt_thr_event_u0_int_raw : R/WTC/SS; bitpos: [0]; default: 0;
|
|
||||||
* The raw interrupt status bit for the PCNT_CNT_THR_EVENT_U0_INT interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u0_int_raw:1;
|
|
||||||
/** cnt_thr_event_u1_int_raw : R/WTC/SS; bitpos: [1]; default: 0;
|
|
||||||
* The raw interrupt status bit for the PCNT_CNT_THR_EVENT_U1_INT interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u1_int_raw:1;
|
|
||||||
/** cnt_thr_event_u2_int_raw : R/WTC/SS; bitpos: [2]; default: 0;
|
|
||||||
* The raw interrupt status bit for the PCNT_CNT_THR_EVENT_U2_INT interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u2_int_raw:1;
|
|
||||||
/** cnt_thr_event_u3_int_raw : R/WTC/SS; bitpos: [3]; default: 0;
|
|
||||||
* The raw interrupt status bit for the PCNT_CNT_THR_EVENT_U3_INT interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u3_int_raw:1;
|
|
||||||
uint32_t reserved_4:28;
|
|
||||||
};
|
|
||||||
uint32_t val;
|
|
||||||
} pcnt_int_raw_reg_t;
|
|
||||||
|
|
||||||
/** Type of int_st register
|
|
||||||
* Interrupt status register
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
/** 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.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u0_int_st:1;
|
|
||||||
/** 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.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u1_int_st:1;
|
|
||||||
/** 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.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u2_int_st:1;
|
|
||||||
/** cnt_thr_event_u3_int_st : RO; bitpos: [3]; default: 0;
|
|
||||||
* The masked interrupt status bit for the PCNT_CNT_THR_EVENT_U3_INT interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u3_int_st:1;
|
|
||||||
uint32_t reserved_4:28;
|
|
||||||
};
|
|
||||||
uint32_t val;
|
|
||||||
} pcnt_int_st_reg_t;
|
|
||||||
|
|
||||||
/** Type of int_ena register
|
|
||||||
* Interrupt enable register
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
/** cnt_thr_event_u0_int_ena : R/W; bitpos: [0]; default: 0;
|
|
||||||
* The interrupt enable bit for the PCNT_CNT_THR_EVENT_U0_INT interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u0_int_ena:1;
|
|
||||||
/** cnt_thr_event_u1_int_ena : R/W; bitpos: [1]; default: 0;
|
|
||||||
* The interrupt enable bit for the PCNT_CNT_THR_EVENT_U1_INT interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u1_int_ena:1;
|
|
||||||
/** cnt_thr_event_u2_int_ena : R/W; bitpos: [2]; default: 0;
|
|
||||||
* The interrupt enable bit for the PCNT_CNT_THR_EVENT_U2_INT interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u2_int_ena:1;
|
|
||||||
/** cnt_thr_event_u3_int_ena : R/W; bitpos: [3]; default: 0;
|
|
||||||
* The interrupt enable bit for the PCNT_CNT_THR_EVENT_U3_INT interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u3_int_ena:1;
|
|
||||||
uint32_t reserved_4:28;
|
|
||||||
};
|
|
||||||
uint32_t val;
|
|
||||||
} pcnt_int_ena_reg_t;
|
|
||||||
|
|
||||||
/** Type of int_clr register
|
|
||||||
* Interrupt clear register
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
/** cnt_thr_event_u0_int_clr : WT; bitpos: [0]; default: 0;
|
|
||||||
* Set this bit to clear the PCNT_CNT_THR_EVENT_U0_INT interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u0_int_clr:1;
|
|
||||||
/** cnt_thr_event_u1_int_clr : WT; bitpos: [1]; default: 0;
|
|
||||||
* Set this bit to clear the PCNT_CNT_THR_EVENT_U1_INT interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u1_int_clr:1;
|
|
||||||
/** cnt_thr_event_u2_int_clr : WT; bitpos: [2]; default: 0;
|
|
||||||
* Set this bit to clear the PCNT_CNT_THR_EVENT_U2_INT interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u2_int_clr:1;
|
|
||||||
/** cnt_thr_event_u3_int_clr : WT; bitpos: [3]; default: 0;
|
|
||||||
* Set this bit to clear the PCNT_CNT_THR_EVENT_U3_INT interrupt.
|
|
||||||
*/
|
|
||||||
uint32_t cnt_thr_event_u3_int_clr:1;
|
|
||||||
uint32_t reserved_4:28;
|
|
||||||
};
|
|
||||||
uint32_t val;
|
|
||||||
} pcnt_int_clr_reg_t;
|
|
||||||
|
|
||||||
|
|
||||||
/** Group: Version Register */
|
|
||||||
/** Type of date register
|
|
||||||
* PCNT version control register
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
/** date : R/W; bitpos: [31:0]; default: 37778192;
|
|
||||||
* Version control register.
|
|
||||||
*/
|
|
||||||
uint32_t date:32;
|
|
||||||
};
|
|
||||||
uint32_t val;
|
|
||||||
} 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];
|
|
||||||
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_ctrl_reg_t ctrl;
|
|
||||||
uint32_t reserved_074[34];
|
|
||||||
volatile pcnt_date_reg_t date;
|
|
||||||
} pcnt_dev_t;
|
|
||||||
|
|
||||||
extern pcnt_dev_t PCNT;
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
_Static_assert(sizeof(pcnt_dev_t) == 0x100, "Invalid size of pcnt_dev_t structure");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
@@ -158,7 +158,11 @@ It is recommended to remove the unused watch point by :cpp:func:`pcnt_unit_remov
|
|||||||
|
|
||||||
PCNT unit can be configured to watch a specific value increment (can be positive or negative) that you are interested in. The function of watching value increment is also called **Watch Step**. To install watch step requires enabling :cpp:member:`pcnt_unit_config_t::en_step_notify_up` or :cpp:member:`pcnt_unit_config_t::en_step_notify_down`. The step interval itself can not exceed the range set in :cpp:type:`pcnt_unit_config_t` by :cpp:member:`pcnt_unit_config_t::low_limit` and :cpp:member:`pcnt_unit_config_t::high_limit`.When the counter increment reaches step interval, a watch event will be triggered and notify you by interrupt if any watch event callback has ever registered in :cpp:func:`pcnt_unit_register_event_callbacks`. See :ref:`pcnt-register-event-callbacks` for how to register event callbacks.
|
PCNT unit can be configured to watch a specific value increment (can be positive or negative) that you are interested in. The function of watching value increment is also called **Watch Step**. To install watch step requires enabling :cpp:member:`pcnt_unit_config_t::en_step_notify_up` or :cpp:member:`pcnt_unit_config_t::en_step_notify_down`. The step interval itself can not exceed the range set in :cpp:type:`pcnt_unit_config_t` by :cpp:member:`pcnt_unit_config_t::low_limit` and :cpp:member:`pcnt_unit_config_t::high_limit`.When the counter increment reaches step interval, a watch event will be triggered and notify you by interrupt if any watch event callback has ever registered in :cpp:func:`pcnt_unit_register_event_callbacks`. See :ref:`pcnt-register-event-callbacks` for how to register event callbacks.
|
||||||
|
|
||||||
The watch step can be added and removed by :cpp:func:`pcnt_unit_add_watch_step` and :cpp:func:`pcnt_unit_remove_watch_step`. You can not add multiple watch step, otherwise it will return error :c:macro:`ESP_ERR_INVALID_STATE`。
|
The watch step can be added and removed by :cpp:func:`pcnt_unit_add_watch_step` and :cpp:func:`pcnt_unit_remove_watch_step`. The parameter ``step_interval`` can be positive(step forward, e.g., [N]->[N+1]->[N+2]->...) or negative(step backward, e.g., [N]->[N-1]->[N-2]->...). The same direction can only add one watch step, otherwise it will return error :c:macro:`ESP_ERR_INVALID_STATE`.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Due to hardware limitations, some chips may only support adding one direction of watch step. Please check the return value of :cpp:func:`pcnt_unit_add_watch_step` for more details.
|
||||||
|
|
||||||
It is recommended to remove the unused watch step by :cpp:func:`pcnt_unit_remove_watch_step` to recycle the watch step resources.
|
It is recommended to remove the unused watch step by :cpp:func:`pcnt_unit_remove_watch_step` to recycle the watch step resources.
|
||||||
|
|
||||||
@@ -318,8 +322,7 @@ The internal hardware counter will be cleared to zero automatically when it reac
|
|||||||
.. list::
|
.. list::
|
||||||
|
|
||||||
1. Enable :cpp:member:`pcnt_unit_config_t::accum_count` when installing the PCNT unit.
|
1. Enable :cpp:member:`pcnt_unit_config_t::accum_count` when installing the PCNT unit.
|
||||||
:SOC_PCNT_SUPPORT_STEP_NOTIFY: 2. Add the high/low limit as the :ref:`pcnt-watch-points` or add watch step as the :ref:`pcnt-step-notify`.
|
2. Add the high/low limit as the :ref:`pcnt-watch-points`.
|
||||||
:not SOC_PCNT_SUPPORT_STEP_NOTIFY: 2. Add the high/low limit as the :ref:`pcnt-watch-points`.
|
|
||||||
3. Now, the returned count value from the :cpp:func:`pcnt_unit_get_count` function not only reflects the hardware's count value, but also accumulates the high/low overflow loss to it.
|
3. Now, the returned count value from the :cpp:func:`pcnt_unit_get_count` function not only reflects the hardware's count value, but also accumulates the high/low overflow loss to it.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
@@ -158,7 +158,11 @@ PCNT 单元可被设置为观察几个特定的数值,这些被观察的数值
|
|||||||
|
|
||||||
PCNT 单元可被设置为观察一个特定的数值增量(可以是正方向或负方向),这个观察数值增量的功能被称为 **观察步进**。启用观察步进需要使能 :cpp:member:`pcnt_unit_config_t::en_step_notify_up` 或 :cpp:member:`pcnt_unit_config_t::en_step_notify_down` 选项。 步进间隔不能超过 :cpp:type:`pcnt_unit_config_t` 设置的范围,最小值和最大值分别为 :cpp:member:`pcnt_unit_config_t::low_limit` 和 :cpp:member:`pcnt_unit_config_t::high_limit`。当计数器增量到达步进间隔时,会触发一个观察事件,如果在 :cpp:func:`pcnt_unit_register_event_callbacks` 注册过事件回调函数,该事件就会通过中断发送通知。关于如何注册事件回调函数,请参考 :ref:`pcnt-register-event-callbacks`。
|
PCNT 单元可被设置为观察一个特定的数值增量(可以是正方向或负方向),这个观察数值增量的功能被称为 **观察步进**。启用观察步进需要使能 :cpp:member:`pcnt_unit_config_t::en_step_notify_up` 或 :cpp:member:`pcnt_unit_config_t::en_step_notify_down` 选项。 步进间隔不能超过 :cpp:type:`pcnt_unit_config_t` 设置的范围,最小值和最大值分别为 :cpp:member:`pcnt_unit_config_t::low_limit` 和 :cpp:member:`pcnt_unit_config_t::high_limit`。当计数器增量到达步进间隔时,会触发一个观察事件,如果在 :cpp:func:`pcnt_unit_register_event_callbacks` 注册过事件回调函数,该事件就会通过中断发送通知。关于如何注册事件回调函数,请参考 :ref:`pcnt-register-event-callbacks`。
|
||||||
|
|
||||||
观察步进分别可以通过 :cpp:func:`pcnt_unit_add_watch_step` 和 :cpp:func:`pcnt_unit_remove_watch_step` 进行添加和删除。不能同时添加多个观察步进,否则将返回错误 :c:macro:`ESP_ERR_INVALID_STATE`。
|
观察步进分别可以通过 :cpp:func:`pcnt_unit_add_watch_step` 和 :cpp:func:`pcnt_unit_remove_watch_step` 进行添加和删除。参数 ``step_interval`` 的为正数表示正方向的步进(例如 [N]->[N+1]->[N+2]->...),为负数表示负方向的步进(例如 [N]->[N-1]->[N-2]->...)。同一个方向只能添加一个观察步进,否则将返回错误 :c:macro:`ESP_ERR_INVALID_STATE`。
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
由于硬件上的限制,部分芯片可能只能支持添加一个方向的观察步进,请检查 :cpp:func:`pcnt_unit_add_watch_step` 的返回值。
|
||||||
|
|
||||||
建议通过 :cpp:func:`pcnt_unit_remove_watch_step` 删除未使用的观察步进来回收资源。
|
建议通过 :cpp:func:`pcnt_unit_remove_watch_step` 删除未使用的观察步进来回收资源。
|
||||||
|
|
||||||
@@ -318,8 +322,7 @@ PCNT 内部的硬件计数器会在计数达到高/低门限的时候自动清
|
|||||||
.. list::
|
.. list::
|
||||||
|
|
||||||
1. 在安装 PCNT 计数单元的时候使能 :cpp:member:`pcnt_unit_config_t::accum_count` 选项。
|
1. 在安装 PCNT 计数单元的时候使能 :cpp:member:`pcnt_unit_config_t::accum_count` 选项。
|
||||||
:SOC_PCNT_SUPPORT_STEP_NOTIFY: 2. 将高/低计数门限设置为 :ref:`pcnt-watch-points` 或添加观察步进 :ref:`pcnt-step-notify`
|
2. 将高/低计数门限设置为 :ref:`pcnt-watch-points`。
|
||||||
:not SOC_PCNT_SUPPORT_STEP_NOTIFY: 2. 将高/低计数门限设置为 :ref:`pcnt-watch-points`。
|
|
||||||
3. 现在,:cpp:func:`pcnt_unit_get_count` 函数返回的计数值就会包含硬件计数器当前的计数值,累加上计数器溢出造成的损失。
|
3. 现在,:cpp:func:`pcnt_unit_get_count` 函数返回的计数值就会包含硬件计数器当前的计数值,累加上计数器溢出造成的损失。
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
Reference in New Issue
Block a user