From f0bea3ce5174c623446823a2b4b62be32e134711 Mon Sep 17 00:00:00 2001 From: morris Date: Mon, 12 Dec 2022 17:36:37 +0800 Subject: [PATCH] mcpwm: support not reset GPIO config at exit By default, the driver will reset the GPIO used by the MCPWM capture channel at exit. But in some special use cases, the same gpio may also be used by another device, which shares the same gpio configuration, resetting the gpio is not expected. Closes https://github.com/espressif/esp-idf/issues/10327 --- components/driver/include/driver/mcpwm_cap.h | 4 +++- components/driver/mcpwm/mcpwm_cap.c | 3 ++- components/driver/mcpwm/mcpwm_private.h | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/components/driver/include/driver/mcpwm_cap.h b/components/driver/include/driver/mcpwm_cap.h index f1bb0307209..f8c545f5c65 100644 --- a/components/driver/include/driver/mcpwm_cap.h +++ b/components/driver/include/driver/mcpwm_cap.h @@ -131,7 +131,7 @@ esp_err_t mcpwm_capture_timer_set_phase_on_sync(mcpwm_cap_timer_handle_t cap_tim * @brief MCPWM capture channel configuration structure */ typedef struct { - int gpio_num; /*!< GPIO used capturing input signal */ + int gpio_num; /*!< GPIO used capturing input signal */ uint32_t prescale; /*!< Prescale of input signal, effective frequency = cap_input_clk/prescale */ struct { uint32_t pos_edge: 1; /*!< Whether to capture on positive edge */ @@ -140,6 +140,8 @@ typedef struct { uint32_t pull_down: 1; /*!< Whether to pull down internally */ uint32_t invert_cap_signal: 1; /*!< Invert the input capture signal */ uint32_t io_loop_back: 1; /*!< For debug/test, the signal output from the GPIO will be fed to the input path as well */ + uint32_t keep_io_conf_at_exit: 1; /*!< For debug/test, whether to keep the GPIO configuration when capture channel is deleted. + By default, driver will reset the GPIO pin at exit. */ } flags; /*!< Extra configuration flags for capture channel */ } mcpwm_capture_channel_config_t; diff --git a/components/driver/mcpwm/mcpwm_cap.c b/components/driver/mcpwm/mcpwm_cap.c index 32a3fb1da18..de597c3d6a5 100644 --- a/components/driver/mcpwm/mcpwm_cap.c +++ b/components/driver/mcpwm/mcpwm_cap.c @@ -276,6 +276,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; + cap_chan->flags.reset_io_at_exit = !config->flags.keep_io_conf_at_exit && config->gpio_num >= 0; *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; @@ -296,7 +297,7 @@ esp_err_t mcpwm_del_capture_channel(mcpwm_cap_channel_handle_t cap_channel) int cap_chan_id = cap_channel->cap_chan_id; ESP_LOGD(TAG, "del capture channel (%d,%d)", group->group_id, cap_channel->cap_chan_id); - if (cap_channel->gpio_num >= 0) { + if (cap_channel->flags.reset_io_at_exit) { gpio_reset_pin(cap_channel->gpio_num); } diff --git a/components/driver/mcpwm/mcpwm_private.h b/components/driver/mcpwm/mcpwm_private.h index 826f0b49764..a2f0bcbcb87 100644 --- a/components/driver/mcpwm/mcpwm_private.h +++ b/components/driver/mcpwm/mcpwm_private.h @@ -216,6 +216,9 @@ struct mcpwm_cap_channel_t { 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 + struct { + uint32_t reset_io_at_exit: 1; // Whether to reset the GPIO configuration when capture channel is deleted + } flags; }; mcpwm_group_t *mcpwm_acquire_group_handle(int group_id);