Prechádzať zdrojové kódy

mcpwm: added enable/disable functions

Closes https://github.com/espressif/esp-idf/pull/9523
morris 3 rokov pred
rodič
commit
1d4c08cef4

+ 1 - 1
components/driver/deprecated/mcpwm_legacy.c

@@ -787,7 +787,7 @@ esp_err_t mcpwm_capture_enable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_cha
     mcpwm_ll_capture_enable_negedge(hal->dev, cap_channel, cap_conf->cap_edge & MCPWM_NEG_EDGE);
     mcpwm_ll_capture_enable_posedge(hal->dev, cap_channel, cap_conf->cap_edge & MCPWM_POS_EDGE);
     mcpwm_ll_capture_set_prescale(hal->dev, cap_channel, cap_conf->cap_prescale);
-    // capture feature should be used with interupt, so enable it by default
+    // capture feature should be used with interrupt, so enable it by default
     mcpwm_ll_intr_enable(hal->dev, MCPWM_LL_EVENT_CAPTURE(cap_channel), true);
     mcpwm_ll_intr_clear_capture_status(hal->dev, 1 << cap_channel);
     mcpwm_critical_exit(mcpwm_num);

+ 1 - 1
components/driver/gptimer.c

@@ -318,7 +318,7 @@ esp_err_t gptimer_enable(gptimer_handle_t timer)
     if (timer->pm_lock) {
         ESP_RETURN_ON_ERROR(esp_pm_lock_acquire(timer->pm_lock), TAG, "acquire pm_lock failed");
     }
-    // enable interrupt interupt service
+    // enable interrupt service
     if (timer->intr) {
         ESP_RETURN_ON_ERROR(esp_intr_enable(timer->intr), TAG, "enable interrupt service failed");
     }

+ 32 - 0
components/driver/include/driver/mcpwm_cap.h

@@ -134,6 +134,8 @@ typedef struct {
 /**
  * @brief Create MCPWM capture channel
  *
+ * @note The created capture channel won't be enabled until calling `mcpwm_capture_channel_enable`
+ *
  * @param[in] cap_timer MCPWM capture timer, allocated by `mcpwm_new_capture_timer()`, will be connected to the new capture channel
  * @param[in] config MCPWM capture channel configuration
  * @param[out] ret_cap_channel Returned MCPWM capture channel
@@ -157,6 +159,33 @@ esp_err_t mcpwm_new_capture_channel(mcpwm_cap_timer_handle_t cap_timer, const mc
  */
 esp_err_t mcpwm_del_capture_channel(mcpwm_cap_channel_handle_t cap_channel);
 
+/**
+ * @brief Enable MCPWM capture channel
+ *
+ * @note This function will transit the channel state from init to enable.
+ * @note This function will enable the interrupt service, if it's lazy installed in `mcpwm_capture_channel_register_event_callbacks()`.
+ *
+ * @param[in] cap_channel MCPWM capture channel handle, allocated by `mcpwm_new_capture_channel()`
+ * @return
+ *      - ESP_OK: Enable MCPWM capture channel successfully
+ *      - ESP_ERR_INVALID_ARG: Enable MCPWM capture channel failed because of invalid argument
+ *      - ESP_ERR_INVALID_STATE: Enable MCPWM capture channel failed because the channel is already enabled
+ *      - ESP_FAIL: Enable MCPWM capture channel failed because of other error
+ */
+esp_err_t mcpwm_capture_channel_enable(mcpwm_cap_channel_handle_t cap_channel);
+
+/**
+ * @brief Disable MCPWM capture channel
+ *
+ * @param[in] cap_channel MCPWM capture channel handle, allocated by `mcpwm_new_capture_channel()`
+ * @return
+ *      - ESP_OK: Disable MCPWM capture channel successfully
+ *      - ESP_ERR_INVALID_ARG: Disable MCPWM capture channel failed because of invalid argument
+ *      - ESP_ERR_INVALID_STATE: Disable MCPWM capture channel failed because the channel is not enabled yet
+ *      - ESP_FAIL: Disable MCPWM capture channel failed because of other error
+ */
+esp_err_t mcpwm_capture_channel_disable(mcpwm_cap_channel_handle_t cap_channel);
+
 /**
  * @brief Group of supported MCPWM capture event callbacks
  * @note The callbacks are all running under ISR environment
@@ -168,6 +197,7 @@ typedef struct {
 /**
  * @brief Set event callbacks for MCPWM capture channel
  *
+ * @note The first call to this function needs to be before the call to `mcpwm_capture_channel_enable`
  * @note User can deregister a previously registered callback by calling this function and setting the callback member in the `cbs` structure to NULL.
  *
  * @param[in] cap_channel MCPWM capture channel handle, allocated by `mcpwm_new_capture_channel()`
@@ -176,6 +206,7 @@ typedef struct {
  * @return
  *      - ESP_OK: Set event callbacks successfully
  *      - ESP_ERR_INVALID_ARG: Set event callbacks failed because of invalid argument
+ *      - ESP_ERR_INVALID_STATE: Set event callbacks failed because the channel is not in init state
  *      - ESP_FAIL: Set event callbacks failed because of other error
  */
 esp_err_t mcpwm_capture_channel_register_event_callbacks(mcpwm_cap_channel_handle_t cap_channel, const mcpwm_capture_event_callbacks_t *cbs, void *user_data);
@@ -187,6 +218,7 @@ esp_err_t mcpwm_capture_channel_register_event_callbacks(mcpwm_cap_channel_handl
  * @return
  *      - ESP_OK: Trigger software catch successfully
  *      - ESP_ERR_INVALID_ARG: Trigger software catch failed because of invalid argument
+ *      - ESP_ERR_INVALID_STATE: Trigger software catch failed because the channel is not enabled yet
  *      - ESP_FAIL: Trigger software catch failed because of other error
  */
 esp_err_t mcpwm_capture_channel_trigger_soft_catch(mcpwm_cap_channel_handle_t cap_channel);

+ 40 - 6
components/driver/mcpwm/mcpwm_cap.c

@@ -242,7 +242,6 @@ esp_err_t mcpwm_new_capture_channel(mcpwm_cap_timer_handle_t cap_timer, const mc
     mcpwm_hal_context_t *hal = &group->hal;
     int cap_chan_id = cap_chan->cap_chan_id;
 
-    mcpwm_ll_capture_enable_channel(hal->dev, cap_chan_id, true); // enable channel
     mcpwm_ll_capture_enable_negedge(hal->dev, cap_chan_id, config->flags.neg_edge);
     mcpwm_ll_capture_enable_posedge(hal->dev, cap_chan_id, config->flags.pos_edge);
     mcpwm_ll_invert_input(hal->dev, cap_chan_id, config->flags.invert_cap_signal);
@@ -262,6 +261,7 @@ esp_err_t mcpwm_new_capture_channel(mcpwm_cap_timer_handle_t cap_timer, const mc
     }
 
     cap_chan->gpio_num = config->gpio_num;
+    cap_chan->fsm = MCPWM_CAP_CHAN_FSM_INIT;
     *ret_cap_channel = cap_chan;
     ESP_LOGD(TAG, "new capture channel (%d,%d) at %p", group->group_id, cap_chan_id, cap_chan);
     return ESP_OK;
@@ -275,6 +275,7 @@ err:
 esp_err_t mcpwm_del_capture_channel(mcpwm_cap_channel_handle_t cap_channel)
 {
     ESP_RETURN_ON_FALSE(cap_channel, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
+    ESP_RETURN_ON_FALSE(cap_channel->fsm == MCPWM_CAP_CHAN_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "channel not in init state");
     mcpwm_cap_timer_t *cap_timer = cap_channel->cap_timer;
     mcpwm_group_t *group = cap_timer->group;
     mcpwm_hal_context_t *hal = &group->hal;
@@ -290,14 +291,46 @@ esp_err_t mcpwm_del_capture_channel(mcpwm_cap_channel_handle_t cap_channel)
     mcpwm_ll_intr_clear_status(hal->dev, MCPWM_LL_EVENT_CAPTURE(cap_chan_id));
     portEXIT_CRITICAL(&group->spinlock);
 
-    // disable capture channel
-    mcpwm_ll_capture_enable_channel(group->hal.dev, cap_channel->cap_chan_id, false);
-
     // recycle memory resource
     ESP_RETURN_ON_ERROR(mcpwm_capture_channel_destory(cap_channel), TAG, "destory capture channel failed");
     return ESP_OK;
 }
 
+esp_err_t mcpwm_capture_channel_enable(mcpwm_cap_channel_handle_t cap_channel)
+{
+    ESP_RETURN_ON_FALSE(cap_channel, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
+    ESP_RETURN_ON_FALSE(cap_channel->fsm == MCPWM_CAP_CHAN_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "channel not in init state");
+    mcpwm_hal_context_t *hal = &cap_channel->cap_timer->group->hal;
+
+    // enable interrupt service
+    if (cap_channel->intr) {
+        ESP_RETURN_ON_ERROR(esp_intr_enable(cap_channel->intr), TAG, "enable interrupt service failed");
+    }
+    // enable channel
+    mcpwm_ll_capture_enable_channel(hal->dev, cap_channel->cap_chan_id, true);
+
+    cap_channel->fsm = MCPWM_CAP_CHAN_FSM_ENABLE;
+    return ESP_OK;
+}
+
+esp_err_t mcpwm_capture_channel_disable(mcpwm_cap_channel_handle_t cap_channel)
+{
+    ESP_RETURN_ON_FALSE(cap_channel, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
+    ESP_RETURN_ON_FALSE(cap_channel->fsm == MCPWM_CAP_CHAN_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "channel not in enable state");
+    mcpwm_hal_context_t *hal = &cap_channel->cap_timer->group->hal;
+
+    // disable channel
+    mcpwm_ll_capture_enable_channel(hal->dev, cap_channel->cap_chan_id, false);
+
+    // disable interrupt service
+    if (cap_channel->intr) {
+        ESP_RETURN_ON_ERROR(esp_intr_disable(cap_channel->intr), TAG, "disable interrupt service failed");
+    }
+
+    cap_channel->fsm = MCPWM_CAP_CHAN_FSM_INIT;
+    return ESP_OK;
+}
+
 esp_err_t mcpwm_capture_channel_register_event_callbacks(mcpwm_cap_channel_handle_t cap_channel, const mcpwm_capture_event_callbacks_t *cbs, void *user_data)
 {
     ESP_RETURN_ON_FALSE(cap_channel && cbs, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
@@ -317,8 +350,8 @@ esp_err_t mcpwm_capture_channel_register_event_callbacks(mcpwm_cap_channel_handl
 
     // lazy install interrupt service
     if (!cap_channel->intr) {
-        // we want the interrupt service to be enabled after allocation successfully
-        int isr_flags = MCPWM_INTR_ALLOC_FLAG & ~ ESP_INTR_FLAG_INTRDISABLED;
+        ESP_RETURN_ON_FALSE(cap_channel->fsm == MCPWM_CAP_CHAN_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "channel not in init state");
+        int isr_flags = MCPWM_INTR_ALLOC_FLAG;
         ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(mcpwm_periph_signals.groups[group_id].irq_id, isr_flags,
                             (uint32_t)mcpwm_ll_intr_get_status_reg(hal->dev), MCPWM_LL_EVENT_CAPTURE(cap_chan_id),
                             mcpwm_capture_default_isr, cap_channel, &cap_channel->intr), TAG, "install interrupt service for cap channel failed");
@@ -337,6 +370,7 @@ esp_err_t mcpwm_capture_channel_register_event_callbacks(mcpwm_cap_channel_handl
 esp_err_t mcpwm_capture_channel_trigger_soft_catch(mcpwm_cap_channel_handle_t cap_channel)
 {
     ESP_RETURN_ON_FALSE(cap_channel, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
+    ESP_RETURN_ON_FALSE(cap_channel->fsm == MCPWM_CAP_CHAN_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "channel not enabled yet");
     mcpwm_cap_timer_t *cap_timer = cap_channel->cap_timer;
     mcpwm_group_t *group = cap_timer->group;
 

+ 7 - 1
components/driver/mcpwm/mcpwm_private.h

@@ -193,6 +193,11 @@ typedef enum {
     MCPWM_CAP_TIMER_FSM_ENABLE,
 } mcpwm_cap_timer_fsm_t;
 
+typedef enum {
+    MCPWM_CAP_CHAN_FSM_INIT,
+    MCPWM_CAP_CHAN_FSM_ENABLE,
+} mcpwm_cap_channel_fsm_t;
+
 struct mcpwm_cap_timer_t {
     mcpwm_group_t *group;   // which group the capture timer belongs to
     portMUX_TYPE spinlock;  // spin lock, to prevent concurrently accessing capture timer level resources, including registers
@@ -206,7 +211,8 @@ struct mcpwm_cap_channel_t {
     int cap_chan_id;                  // capture channel ID, index from 0
     mcpwm_cap_timer_t *cap_timer;     // which capture timer that the channel resides in
     uint32_t prescale;                // prescale of capture signal
-    int gpio_num;                 // GPIO number used by the channel
+    int gpio_num;                     // GPIO number used by the channel
+    mcpwm_cap_channel_fsm_t fsm;      // driver FSM
     intr_handle_t intr;               // Interrupt handle
     mcpwm_capture_event_cb_t on_cap;  // Callback function which would be invoked in capture interrupt routine
     void *user_data;                  // user data which would be passed to the capture callback

+ 1 - 1
components/driver/pulse_cnt.c

@@ -283,7 +283,7 @@ esp_err_t pcnt_unit_enable(pcnt_unit_handle_t unit)
     if (unit->pm_lock) {
         ESP_RETURN_ON_ERROR(esp_pm_lock_acquire(unit->pm_lock), TAG, "acquire pm_lock failed");
     }
-    // enable interupt service
+    // enable interrupt service
     if (unit->intr) {
         ESP_RETURN_ON_ERROR(esp_intr_enable(unit->intr), TAG, "enable interrupt service failed");
     }

+ 15 - 0
components/driver/test_apps/mcpwm/main/test_mcpwm_cap.c

@@ -102,6 +102,9 @@ TEST_CASE("mcpwm_capture_ext_gpio", "[mcpwm]")
     uint32_t cap_value[2] = {0};
     TEST_ESP_OK(mcpwm_capture_channel_register_event_callbacks(pps_channel, &cbs, cap_value));
 
+    printf("enable capture channel\r\n");
+    TEST_ESP_OK(mcpwm_capture_channel_enable(pps_channel));
+
     printf("enable and start capture timer\r\n");
     TEST_ESP_OK(mcpwm_capture_timer_enable(cap_timer));
     TEST_ESP_OK(mcpwm_capture_timer_start(cap_timer));
@@ -117,6 +120,7 @@ TEST_CASE("mcpwm_capture_ext_gpio", "[mcpwm]")
     TEST_ASSERT_UINT_WITHIN(100000, clk_src_res / 10, cap_value[1] - cap_value[0]);
 
     printf("uninstall capture channel and timer\r\n");
+    TEST_ESP_OK(mcpwm_capture_channel_disable(pps_channel));
     TEST_ESP_OK(mcpwm_del_capture_channel(pps_channel));
     TEST_ESP_OK(mcpwm_capture_timer_disable(cap_timer));
     TEST_ESP_OK(mcpwm_del_capture_timer(cap_timer));
@@ -154,12 +158,17 @@ TEST_CASE("mcpwm_capture_software_catch", "[mcpwm]")
     test_soft_catch_user_data_t test_callback_data = {};
     TEST_ESP_OK(mcpwm_new_capture_channel(cap_timer, &cap_chan_config, &cap_channel));
 
+    TEST_ESP_ERR(ESP_ERR_INVALID_STATE, mcpwm_capture_channel_trigger_soft_catch(cap_channel));
+
     printf("register event callback for capture channel\r\n");
     mcpwm_capture_event_callbacks_t cbs = {
         .on_cap = soft_cap_callback,
     };
     TEST_ESP_OK(mcpwm_capture_channel_register_event_callbacks(cap_channel, &cbs, &test_callback_data));
 
+    printf("enable capture channel\r\n");
+    TEST_ESP_OK(mcpwm_capture_channel_enable(cap_channel));
+
     printf("enable and start capture timer\r\n");
     TEST_ESP_OK(mcpwm_capture_timer_enable(cap_timer));
     TEST_ESP_OK(mcpwm_capture_timer_start(cap_timer));
@@ -179,6 +188,7 @@ TEST_CASE("mcpwm_capture_software_catch", "[mcpwm]")
     TEST_ASSERT_UINT_WITHIN(80000, clk_src_res / 100, delta);
 
     printf("uninstall capture channel and timer\r\n");
+    TEST_ESP_OK(mcpwm_capture_channel_disable(cap_channel));
     TEST_ESP_OK(mcpwm_capture_timer_disable(cap_timer));
     TEST_ESP_OK(mcpwm_del_capture_channel(cap_channel));
     TEST_ESP_OK(mcpwm_del_capture_timer(cap_timer));
@@ -211,6 +221,7 @@ TEST_CASE("mcpwm_capture_timer_sync_phase_lock", "[mcpwm]")
         .sync_src = soft_sync,
     };
     TEST_ESP_OK(mcpwm_capture_timer_set_phase_on_sync(cap_timer, &sync_config));
+
     mcpwm_cap_channel_handle_t cap_channel = NULL;
     mcpwm_capture_channel_config_t cap_chan_config = {
         .gpio_num = -1, // don't need any GPIO, we use software to trigger a catch
@@ -224,6 +235,9 @@ TEST_CASE("mcpwm_capture_timer_sync_phase_lock", "[mcpwm]")
     uint32_t cap_data;
     TEST_ESP_OK(mcpwm_capture_channel_register_event_callbacks(cap_channel, &cbs, &cap_data));
 
+    printf("enable capture channel\r\n");
+    TEST_ESP_OK(mcpwm_capture_channel_enable(cap_channel));
+
     TEST_ESP_OK(mcpwm_capture_channel_trigger_soft_catch(cap_channel));
     vTaskDelay(pdMS_TO_TICKS(10));
     printf("capture data before sync: %"PRIu32"\r\n", cap_data);
@@ -233,6 +247,7 @@ TEST_CASE("mcpwm_capture_timer_sync_phase_lock", "[mcpwm]")
     vTaskDelay(pdMS_TO_TICKS(10));
     printf("capture data after sync: %"PRIu32"\r\n", cap_data);
     TEST_ASSERT_EQUAL(1000, cap_data);
+    TEST_ESP_OK(mcpwm_capture_channel_disable(cap_channel));
     TEST_ESP_OK(mcpwm_del_capture_channel(cap_channel));
     TEST_ESP_OK(mcpwm_del_capture_timer(cap_timer));
     TEST_ESP_OK(mcpwm_del_sync_src(soft_sync));

+ 1 - 1
components/driver/test_apps/mcpwm/main/test_mcpwm_cmpr.c

@@ -76,7 +76,7 @@ TEST_CASE("mcpwm_comparator_event_callback", "[mcpwm]")
         .group_id = 0,
     };
     mcpwm_comparator_config_t comparator_config = {};
-    printf("install timer, operator and comparator");
+    printf("install timer, operator and comparator\r\n");
     TEST_ESP_OK(mcpwm_new_timer(&timer_config, &timer));
     TEST_ESP_OK(mcpwm_new_operator(&operator_config, &operator));
     TEST_ESP_OK(mcpwm_new_comparator(operator, &comparator_config, &comparator));

+ 4 - 0
components/driver/test_apps/mcpwm/main/test_mcpwm_iram.c

@@ -69,6 +69,9 @@ TEST_CASE("mcpwm_capture_iram_safe", "[mcpwm]")
     uint32_t cap_value[2] = {0};
     TEST_ESP_OK(mcpwm_capture_channel_register_event_callbacks(pps_channel, &cbs, cap_value));
 
+    printf("enable capture channel\r\n");
+    TEST_ESP_OK(mcpwm_capture_channel_enable(pps_channel));
+
     printf("enable and start capture timer\r\n");
     TEST_ESP_OK(mcpwm_capture_timer_enable(cap_timer));
     TEST_ESP_OK(mcpwm_capture_timer_start(cap_timer));
@@ -82,6 +85,7 @@ TEST_CASE("mcpwm_capture_iram_safe", "[mcpwm]")
     TEST_ASSERT_UINT_WITHIN(2000, clk_src_res / 1000, cap_value[1] - cap_value[0]);
 
     printf("uninstall capture channel and timer\r\n");
+    TEST_ESP_OK(mcpwm_capture_channel_disable(pps_channel));
     TEST_ESP_OK(mcpwm_del_capture_channel(pps_channel));
     TEST_ESP_OK(mcpwm_capture_timer_disable(cap_timer));
     TEST_ESP_OK(mcpwm_del_capture_timer(cap_timer));

+ 5 - 0
docs/en/api-reference/peripherals/mcpwm.rst

@@ -814,6 +814,11 @@ The parameter ``user_data`` of :cpp:func:`mcpwm_capture_channel_register_event_c
 
 This function will lazy install interrupt service for the MCPWM capture channel, whereas the service can only be removed in :cpp:type:`mcpwm_del_capture_channel`.
 
+Enable and Disable Capture Channel
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The capture channel is not enabled after allocation by :cpp:func:`mcpwm_new_capture_channel`. You should call :cpp:func:`mcpwm_capture_channel_enable` and :cpp:func:`mcpwm_capture_channel_disable` accordingly to enable or disable the channel. If the interrupt service is lazy installed during registering event callbacks for the channel in :cpp:func:`mcpwm_capture_channel_register_event_callbacks`, :cpp:func:`mcpwm_capture_channel_enable` will enable the interrupt service as well.
+
 Enable and Disable Capture Timer
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

+ 1 - 1
docs/en/migration-guides/release-5.x/peripherals.rst

@@ -308,7 +308,7 @@ LCD
     - ``mcpwm_fault_set_oneshot_mode``, ``mcpwm_fault_set_cyc_mode`` are replaced by :cpp:func:`mcpwm_operator_set_brake_on_fault` and :cpp:func:`mcpwm_generator_set_actions_on_brake_event`.
     - ``mcpwm_capture_enable`` is removed. It's duplicated to :cpp:func:`mcpwm_capture_enable_channel`.
     - ``mcpwm_capture_disable`` is removed. It's duplicated to :cpp:func:`mcpwm_capture_capture_disable_channel`.
-    - ``mcpwm_capture_enable_channel`` and ``mcpwm_capture_disable_channel`` are replaced by :cpp:func:`mcpwm_new_capture_channel` and :cpp:func:`mcpwm_del_capture_channel`.
+    - ``mcpwm_capture_enable_channel`` and ``mcpwm_capture_disable_channel`` are replaced by :cpp:func:`mcpwm_capture_channel_enable` and :cpp:func:`mcpwm_capture_channel_disable`.
     - ``mcpwm_capture_signal_get_value`` and ``mcpwm_capture_signal_get_edge``: Capture timer count value and capture edge are provided in the capture event callback, via :cpp:type:`mcpwm_capture_event_data_t`. Capture data are only valuable when capture event happens. Providing single API to fetch capture data is meaningless.
     - ``mcpwm_sync_enable`` is removed. It's duplicated to :cpp:func:`mcpwm_sync_configure`.
     - ``mcpwm_sync_configure`` is replaced by :cpp:func:`mcpwm_timer_set_phase_on_sync`.

+ 9 - 0
examples/peripherals/mcpwm/mcpwm_bldc_hall_control/main/mcpwm_bldc_hall_control_example_main.c

@@ -321,6 +321,15 @@ void app_main(void)
         ESP_ERROR_CHECK(mcpwm_capture_channel_register_event_callbacks(cap_channels[i], &cbs, task_to_notify));
     }
 
+    ESP_LOGI(TAG, "Enable capture channels");
+    for (int i = 0; i < 3; i++) {
+        ESP_ERROR_CHECK(mcpwm_capture_channel_enable(cap_channels[i]));
+    }
+
+    ESP_LOGI(TAG, "Enable and start capture timer");
+    ESP_ERROR_CHECK(mcpwm_capture_timer_enable(cap_timer));
+    ESP_ERROR_CHECK(mcpwm_capture_timer_start(cap_timer));
+
     ESP_LOGI(TAG, "Start a timer to adjust motor speed periodically");
     esp_timer_handle_t periodic_timer = NULL;
     const esp_timer_create_args_t periodic_timer_args = {

+ 3 - 0
examples/peripherals/mcpwm/mcpwm_capture_hc_sr04/main/mcpwm_capture_hc_sr04.c

@@ -83,6 +83,9 @@ void app_main(void)
     };
     ESP_ERROR_CHECK(mcpwm_capture_channel_register_event_callbacks(cap_chan, &cbs, cur_task));
 
+    ESP_LOGI(TAG, "Enable capture channel");
+    ESP_ERROR_CHECK(mcpwm_capture_channel_enable(cap_chan));
+
     ESP_LOGI(TAG, "Configure Trig pin");
     gpio_config_t io_conf = {
         .mode = GPIO_MODE_OUTPUT,

+ 1 - 0
examples/peripherals/mcpwm/mcpwm_capture_hc_sr04/pytest_hc_sr04.py

@@ -12,5 +12,6 @@ def test_hc_sr04_example(dut: Dut) -> None:
     dut.expect_exact('example: Install capture timer')
     dut.expect_exact('example: Install capture channel')
     dut.expect_exact('example: Register capture callback')
+    dut.expect_exact('example: Enable capture channel')
     dut.expect_exact('example: Configure Trig pin')
     dut.expect_exact('example: Enable and start capture timer')