feat(pcnt): add support for step notify

PCNT can add watch of value increment that we call step notify.
This commit add a step notify driver and a test for the driver.

Closes https://github.com/espressif/esp-idf/issues/9604
Closes https://github.com/espressif/esp-idf/issues/12136
This commit is contained in:
Chen Jichang
2024-06-19 21:42:03 +08:00
parent c9a504cdcb
commit d81546628a
9 changed files with 340 additions and 26 deletions
@@ -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
*/
@@ -52,7 +52,7 @@ typedef bool (*pcnt_watch_cb_t)(pcnt_unit_handle_t unit, const pcnt_watch_event_
* @note When CONFIG_PCNT_ISR_IRAM_SAFE is enabled, the callback itself and functions callbed by it should be placed in IRAM.
*/
typedef struct {
pcnt_watch_cb_t on_reach; /*!< Called when PCNT unit counter reaches any watch point */
pcnt_watch_cb_t on_reach; /*!< Called when PCNT unit counter reaches any watch point or step notify*/
} pcnt_event_callbacks_t;
/**
@@ -65,6 +65,10 @@ typedef struct {
if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) */
struct {
uint32_t accum_count: 1; /*!< Whether to accumulate the count value when overflows at the high/low limit */
#if SOC_PCNT_SUPPORT_STEP_NOTIFY
uint32_t en_step_notify_up: 1; /*!< Enable step notify in the positive direction*/
uint32_t en_step_notify_down: 1; /*!< Enable step notify in the negative direction*/
#endif
} flags; /*!< Extra flags */
} pcnt_unit_config_t;
@@ -283,7 +287,6 @@ esp_err_t pcnt_unit_register_event_callbacks(pcnt_unit_handle_t unit, const pcnt
/**
* @brief Add a watch point for PCNT unit, PCNT will generate an event when the counter value reaches the watch point value
*
*
* @param[in] unit PCNT unit handle created by `pcnt_new_unit()`
* @param[in] watch_point Value to be watched
* @return
@@ -308,6 +311,31 @@ esp_err_t pcnt_unit_add_watch_point(pcnt_unit_handle_t unit, int watch_point);
*/
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
*
* @param[in] unit PCNT unit handle created by `pcnt_new_unit()`
* @param[in] step_interval PCNT step notify interval value
* @return
* - 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_STATE: Add step notify failed because the step notify has already been added
* - ESP_FAIL: Add step notify failed because of other error
*/
esp_err_t pcnt_unit_add_watch_step(pcnt_unit_handle_t unit, int step_interval);
/**
* @brief Remove a step notify for PCNT unit
*
* @param[in] unit PCNT unit handle created by `pcnt_new_unit()`
* @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_watch_step(pcnt_unit_handle_t unit);
/**
* @brief Create PCNT channel for specific unit, each PCNT has several channels associated with it
*