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:
@@ -25,6 +25,7 @@ PCNT 的功能从以下几个方面进行说明:
|
||||
- :ref:`pcnt-resource-allocation` - 说明如何通过配置分配 PCNT 单元和通道,以及在相应操作完成之后,如何回收单元和通道。
|
||||
- :ref:`pcnt-setup-channel-actions` - 说明如何设置通道针对不同信号沿和电平进行操作。
|
||||
- :ref:`pcnt-watch-points` - 说明如何配置观察点,即当计数达到某个数值时,命令 PCNT 单元触发某个事件。
|
||||
:SOC_PCNT_SUPPORT_STEP_NOTIFY: - :ref:`pcnt-step-notify` - 说明如何配置观察步进,即当计数增量达到某个数值时,命令 PCNT 单元触发某个事件。
|
||||
- :ref:`pcnt-register-event-callbacks` - 说明如何将您的代码挂载到观察点事件的回调函数上。
|
||||
- :ref:`pcnt-set-glitch-filter` - 说明如何使能毛刺滤波器并设置其时序参数。
|
||||
:SOC_PCNT_SUPPORT_CLEAR_SIGNAL: - :ref:`pcnt-set-clear-signal` - 说明如何使能外部清零信号并设置其参数。
|
||||
@@ -47,9 +48,13 @@ PCNT 单元和通道分别用 :cpp:type:`pcnt_unit_handle_t` 与 :cpp:type:`pcnt
|
||||
|
||||
安装 PCNT 单元时,需要先完成配置 :cpp:type:`pcnt_unit_config_t`:
|
||||
|
||||
- :cpp:member:`pcnt_unit_config_t::low_limit` 与 :cpp:member:`pcnt_unit_config_t::high_limit` 用于指定内部计数器的最小值和最大值。当计数器超过任一限值时,计数器将归零。
|
||||
- :cpp:member:`pcnt_unit_config_t::accum_count` 用于设置是否需要软件在硬件计数值溢出的时候进行累加保存,这有助于“拓宽”计数器的实际位宽。默认情况下,计数器的位宽最高只有 16 比特。请参考 :ref:`pcnt-compensate-overflow-loss` 了解如何利用此功能来补偿硬件计数器的溢出损失。
|
||||
- :cpp:member:`pcnt_unit_config_t::intr_priority` 设置中断的优先级。如果设置为 ``0``,则会分配一个默认优先级的中断,否则会使用指定的优先级。
|
||||
.. list::
|
||||
|
||||
- :cpp:member:`pcnt_unit_config_t::low_limit` 与 :cpp:member:`pcnt_unit_config_t::high_limit` 用于指定内部计数器的最小值和最大值。当计数器超过任一限值时,计数器将归零。
|
||||
- :cpp:member:`pcnt_unit_config_t::accum_count` 用于设置是否需要软件在硬件计数值溢出的时候进行累加保存,这有助于“拓宽”计数器的实际位宽。默认情况下,计数器的位宽最高只有 16 比特。请参考 :ref:`pcnt-compensate-overflow-loss` 了解如何利用此功能来补偿硬件计数器的溢出损失。
|
||||
:SOC_PCNT_SUPPORT_STEP_NOTIFY: - :cpp:member:`pcnt_unit_config_t::en_step_notify_up` 配置是否使能观察正方向步进。
|
||||
:SOC_PCNT_SUPPORT_STEP_NOTIFY: - :cpp:member:`pcnt_unit_config_t::en_step_notify_down` 配置是否使能观察负方向步进。
|
||||
- :cpp:member:`pcnt_unit_config_t::intr_priority` 设置中断的优先级。如果设置为 ``0``,则会分配一个默认优先级的中断,否则会使用指定的优先级。
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -141,7 +146,36 @@ PCNT 单元可被设置为观察几个特定的数值,这些被观察的数值
|
||||
|
||||
由于硬件上的限制,在添加一个新的观察点后,你需要调用 :cpp:func:`pcnt_unit_clear_count` 函数来使之生效。
|
||||
|
||||
.. _pcnt-register-event-callbacks:
|
||||
.. only:: SOC_PCNT_SUPPORT_STEP_NOTIFY
|
||||
|
||||
.. _pcnt-step-notify:
|
||||
|
||||
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`。
|
||||
|
||||
观察步进分别可以通过 :cpp:func:`pcnt_unit_add_watch_step` 和 :cpp:func:`pcnt_unit_remove_watch_step` 进行添加和删除。不能同时添加多个观察步进,否则将返回错误 :c:macro:`ESP_ERR_INVALID_STATE`。
|
||||
|
||||
建议通过 :cpp:func:`pcnt_unit_remove_watch_step` 删除未使用的观察步进来回收资源。
|
||||
|
||||
.. note::
|
||||
|
||||
当观察步进和观察点同时被触发时,只会产生一次中断事件。
|
||||
步进间隔必须是 :cpp:member:`pcnt_unit_config_t::low_limit` 或 :cpp:member:`pcnt_unit_config_t::high_limit` 的因数。
|
||||
|
||||
.. code:: c
|
||||
|
||||
// add positive direction step notify with 100 step intervals
|
||||
ESP_ERROR_CHECK(pcnt_unit_add_watch_step(pcnt_unit, 100));
|
||||
|
||||
.. _pcnt-register-event-callbacks:
|
||||
|
||||
.. only:: not SOC_PCNT_SUPPORT_STEP_NOTIFY
|
||||
|
||||
.. _pcnt-register-event-callbacks:
|
||||
|
||||
|
||||
|
||||
注册事件回调函数
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -152,10 +186,18 @@ PCNT 单元可被设置为观察几个特定的数值,这些被观察的数值
|
||||
|
||||
可通过 ``user_ctx`` 将函数上下文保存到 :cpp:func:`pcnt_unit_register_event_callbacks` 中,这些数据会直接传递给回调函数。
|
||||
|
||||
驱动程序会将特定事件的数据写入回调函数中,例如,观察点事件数据被声明为 :cpp:type:`pcnt_watch_event_data_t`:
|
||||
.. only:: SOC_PCNT_SUPPORT_STEP_NOTIFY
|
||||
|
||||
- :cpp:member:`pcnt_watch_event_data_t::watch_point_value` 用于保存触发该事件的观察点数值。
|
||||
- :cpp:member:`pcnt_watch_event_data_t::zero_cross_mode` 用于保存上一次 PCNT 单元的过零模式,:cpp:type:`pcnt_unit_zero_cross_mode_t` 中列出了所有可能的过零模式。通常,不同的过零模式意味着不同的 **计数方向** 和 **计数步长**。
|
||||
驱动程序会将特定事件的数据写入回调函数中,例如,观察点事件或观察步进事件数据被声明为 :cpp:type:`pcnt_watch_event_data_t`:
|
||||
|
||||
.. only:: not SOC_PCNT_SUPPORT_STEP_NOTIFY
|
||||
|
||||
驱动程序会将特定事件的数据写入回调函数中,例如,观察点事件数据被声明为 :cpp:type:`pcnt_watch_event_data_t`:
|
||||
|
||||
.. list::
|
||||
:SOC_PCNT_SUPPORT_STEP_NOTIFY: - :cpp:member:`pcnt_watch_event_data_t::watch_point_value` 用于保存触发该事件的观察点或观察步进的数值。
|
||||
:not SOC_PCNT_SUPPORT_STEP_NOTIFY: - :cpp:member:`pcnt_watch_event_data_t::watch_point_value` 用于保存触发该事件的观察点数值。
|
||||
- :cpp:member:`pcnt_watch_event_data_t::zero_cross_mode` 用于保存上一次 PCNT 单元的过零模式,:cpp:type:`pcnt_unit_zero_cross_mode_t` 中列出了所有可能的过零模式。通常,不同的过零模式意味着不同的 **计数方向** 和 **计数步长**。
|
||||
|
||||
注册回调函数会导致中断服务延迟安装,因此回调函数只能在 PCNT 单元被 :cpp:func:`pcnt_unit_enable` 使能之前调用。否则,回调函数会返回错误 :c:macro:`ESP_ERR_INVALID_STATE`。
|
||||
|
||||
@@ -284,7 +326,10 @@ PCNT 内部的硬件计数器会在计数达到高/低门限的时候自动清
|
||||
|
||||
.. note::
|
||||
|
||||
:cpp:func:`pcnt_unit_clear_count` 会复位该软件累加器。
|
||||
.. list::
|
||||
|
||||
- :cpp:func:`pcnt_unit_clear_count` 会复位该软件累加器。
|
||||
:SOC_PCNT_SUPPORT_STEP_NOTIFY: - 设置观察步进后,同时也会启用软件累加器。
|
||||
|
||||
.. _pcnt-power-management:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user