diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index a90ec57a66..075d4161b5 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -21,11 +21,6 @@ if(CONFIG_SOC_I2C_SUPPORTED) list(APPEND srcs "i2c/i2c.c") endif() -# MCPWM legacy driver -if(CONFIG_SOC_MCPWM_SUPPORTED) - list(APPEND srcs "deprecated/mcpwm_legacy.c") -endif() - # RMT legacy driver if(CONFIG_SOC_RMT_SUPPORTED) list(APPEND srcs "deprecated/rmt_legacy.c") diff --git a/components/driver/deprecated/driver/mcpwm.h b/components/driver/deprecated/driver/mcpwm.h deleted file mode 100644 index 1c4b8a48cf..0000000000 --- a/components/driver/deprecated/driver/mcpwm.h +++ /dev/null @@ -1,553 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include -#include -#include "esp_err.h" -#include "driver/mcpwm_types_legacy.h" - -#if !CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN -#warning "legacy MCPWM driver is deprecated, please migrate to the new driver (include driver/mcpwm_prelude.h)" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief This function initializes each gpio signal for MCPWM - * - * @note This function initializes one gpio at a time. - * - * @param mcpwm_num set MCPWM unit - * @param io_signal set MCPWM signals, each MCPWM unit has 6 output(MCPWMXA, MCPWMXB) and 9 input(SYNC_X, FAULT_X, CAP_X) - * 'X' is timer_num(0-2) - * @param gpio_num set this to configure gpio for MCPWM, if you want to use gpio16, gpio_num = 16 - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_gpio_init(mcpwm_unit_t mcpwm_num, mcpwm_io_signals_t io_signal, int gpio_num); - -/** - * @brief Initialize MCPWM gpio structure - * - * @note This function initialize a group of MCPWM GPIOs at a time. - * - * @param mcpwm_num set MCPWM unit - * @param mcpwm_pin MCPWM pin structure - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_set_pin(mcpwm_unit_t mcpwm_num, const mcpwm_pin_config_t *mcpwm_pin); - -/** - * @brief Initialize MCPWM parameters - * @note The default resolution configured for MCPWM timer is 1M, it can be changed by `mcpwm_timer_set_resolution`. - * @note The default resolution configured for MCPWM group can be different on different esp targets (because of different clock source). - * You can change the group resolution by mcpwm_group_set_resolution() - * @note If you want to change the preset resolution of MCPWM group and timer, please call them before this function. - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers. - * @param mcpwm_conf configure structure mcpwm_config_t - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_config_t *mcpwm_conf); - -/** - * @brief Set resolution of the MCPWM group - * @note This will override default resolution of MCPWM group. - * @note This WILL NOT automatically update PWM frequency and duty. Please call `mcpwm_set_frequency` and `mcpwm_set_duty` manually to reflect the change. - * @note The group resolution must be an integral multiple of timer resolution. - * - * @param mcpwm_num set MCPWM unit - * @param resolution set expected frequency resolution - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_group_set_resolution(mcpwm_unit_t mcpwm_num, unsigned long int resolution); - -/** - * @brief Set resolution of each timer - * @note This will override default resolution of timer(=1,000,000). - * @note This WILL NOT automatically update PWM frequency and duty. Please call `mcpwm_set_frequency` and `mcpwm_set_duty` manually to reflect the change. - * @note The group resolution must be an integral multiple of timer resolution. - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param resolution set expected frequency resolution - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_timer_set_resolution(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, unsigned long int resolution); - -/** - * @brief Set frequency(in Hz) of MCPWM timer - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param frequency set the frequency in Hz of each timer - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_set_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint32_t frequency); - -/** - * @brief Set duty cycle of each operator(MCPWMXA/MCPWMXB) - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param gen set the generator(MCPWMXA/MCPWMXB), 'X' is operator number selected - * @param duty set duty cycle in %(i.e for 62.3% duty cycle, duty = 62.3) of each operator - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_set_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, float duty); - -/** - * @brief Set duty cycle of each operator(MCPWMXA/MCPWMXB) in us - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param gen set the generator(MCPWMXA/MCPWMXB), 'x' is operator number selected - * @param duty_in_us set duty value in microseconds of each operator - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_set_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, uint32_t duty_in_us); - -/** - * @brief Set duty either active high or active low(out of phase/inverted) - * @note - * Call this function every time after mcpwm_set_signal_high or mcpwm_set_signal_low to resume with previously set duty cycle - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param gen set the generator(MCPWMXA/MCPWMXB), 'x' is operator number selected - * @param duty_type set active low or active high duty type - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_set_duty_type(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, mcpwm_duty_type_t duty_type); - -/** - * @brief Get frequency of timer - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * - * @return - * - frequency of timer - */ -uint32_t mcpwm_get_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num); - -/** - * @brief Get duty cycle of each operator - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param gen set the generator(MCPWMXA/MCPWMXB), 'x' is operator number selected - * - * @return - * - duty cycle in % of each operator(56.7 means duty is 56.7%) - */ -float mcpwm_get_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t gen); - -/** - * @brief Get duty cycle of each operator in us - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param gen set the generator(MCPWMXA/MCPWMXB), 'x' is operator number selected - * - * @return - * - duty cycle in us of each operator - */ -uint32_t mcpwm_get_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t gen); - -/** - * @brief Use this function to set MCPWM signal high - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param gen set the operator(MCPWMXA/MCPWMXB), 'x' is timer number selected - * - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_set_signal_high(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen); - -/** - * @brief Use this function to set MCPWM signal low - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param gen set the operator(MCPWMXA/MCPWMXB), 'x' is timer number selected - * - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_set_signal_low(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen); - -/** - * @brief Start MCPWM signal on timer 'x' - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_start(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num); - -/** - * @brief Start MCPWM signal on timer 'x' - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_stop(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num); - -/** - * @brief Initialize carrier configuration - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param carrier_conf configure structure mcpwm_carrier_config_t - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_carrier_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_carrier_config_t *carrier_conf); - -/** - * @brief Enable MCPWM carrier submodule, for respective timer - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_carrier_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num); - -/** - * @brief Disable MCPWM carrier submodule, for respective timer - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_carrier_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num); - -/** - * @brief Set period of carrier - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param carrier_period set the carrier period of each timer, carrier period = (carrier_period + 1)*800ns - * (carrier_period <= 15) - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_carrier_set_period(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_period); - -/** - * @brief Set duty_cycle of carrier - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param carrier_duty set duty_cycle of carrier , carrier duty cycle = carrier_duty*12.5% - * (chop_duty <= 7) - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_carrier_set_duty_cycle(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_duty); - -/** - * @brief Enable and set width of first pulse in carrier oneshot mode - * - * @note The carrier oneshot pulse can't disabled. - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param pulse_width set pulse width of first pulse in oneshot mode, width = (carrier period)*(pulse_width +1) - * (pulse_width <= 15) - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_carrier_oneshot_mode_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t pulse_width); - -/** - * @brief Enable or disable carrier output inversion - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param carrier_ivt_mode enable or disable carrier output inversion - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_carrier_output_invert(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, - mcpwm_carrier_out_ivt_t carrier_ivt_mode); - -/** - * @brief Enable and initialize deadtime for each MCPWM timer - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param dt_mode set deadtime mode - * @param red set rising edge delay = (red + 1) * MCPWM Group Resolution (default to 100ns, can be changed by `mcpwm_group_set_resolution`) - * @param fed set rising edge delay = (fed + 1) * MCPWM Group Resolution (default to 100ns, can be changed by `mcpwm_group_set_resolution`) - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_deadtime_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_deadtime_type_t dt_mode, - uint32_t red, uint32_t fed); - -/** - * @brief Disable deadtime on MCPWM timer - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_deadtime_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num); - -/** - * @brief Initialize fault submodule, currently low level triggering is not supported - * - * @param mcpwm_num set MCPWM unit - * @param intput_level set fault signal level, which will cause fault to occur - * @param fault_sig set the fault pin, which needs to be enabled - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_fault_init(mcpwm_unit_t mcpwm_num, mcpwm_fault_input_level_t intput_level, mcpwm_fault_signal_t fault_sig); - -/** - * @brief Set oneshot mode on fault detection, once fault occur in oneshot mode reset is required to resume MCPWM signals - * @note - * currently low level triggering is not supported - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param fault_sig set the fault pin, which needs to be enabled for oneshot mode - * @param action_on_pwmxa action to be taken on MCPWMXA when fault occurs, either no change or high or low or toggle - * @param action_on_pwmxb action to be taken on MCPWMXB when fault occurs, either no change or high or low or toggle - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_fault_set_oneshot_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig, - mcpwm_output_action_t action_on_pwmxa, mcpwm_output_action_t action_on_pwmxb); - -/** - * @brief Set cycle-by-cycle mode on fault detection, once fault occur in cyc mode MCPWM signal resumes as soon as fault signal becomes inactive - * @note - * currently low level triggering is not supported - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param fault_sig set the fault pin, which needs to be enabled for cyc mode - * @param action_on_pwmxa action to be taken on MCPWMXA when fault occurs, either no change or high or low or toggle - * @param action_on_pwmxb action to be taken on MCPWMXB when fault occurs, either no change or high or low or toggle - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_fault_set_cyc_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig, - mcpwm_output_action_t action_on_pwmxa, mcpwm_output_action_t action_on_pwmxb); - -/** - * @brief Disable fault signal - * - * @param mcpwm_num set MCPWM unit - * @param fault_sig fault pin, which needs to be disabled - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_fault_deinit(mcpwm_unit_t mcpwm_num, mcpwm_fault_signal_t fault_sig); - -/** - * @brief Enable capture channel - * - * @param mcpwm_num set MCPWM unit - * @param cap_channel capture channel, which needs to be enabled - * @param cap_conf capture channel configuration - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_capture_enable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_channel_id_t cap_channel, const mcpwm_capture_config_t *cap_conf); - -/** - * @brief Disable capture channel - * - * @param mcpwm_num set MCPWM unit - * @param cap_channel capture channel, which needs to be disabled - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_capture_disable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_channel_id_t cap_channel); - -/** - * @brief Get capture value - * - * @param mcpwm_num set MCPWM unit - * @param cap_sig capture channel on which value is to be measured - * - * @return - * Captured value - */ -uint32_t mcpwm_capture_signal_get_value(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig); - -/** - * @brief Get capture timer's resolution - * - * @param mcpwm_num set MCPWM unit - * @return Capture timer's resolution - */ -uint32_t mcpwm_capture_get_resolution(mcpwm_unit_t mcpwm_num); - -/** - * @brief Get edge of capture signal - * - * @param mcpwm_num set MCPWM unit - * @param cap_sig capture channel of whose edge is to be determined - * - * @return - * Capture signal edge: 1 - positive edge, 2 - negative edge, 0 - Invalid - */ -uint32_t mcpwm_capture_signal_get_edge(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig); - -/** - * @brief Initialize sync submodule and sets the signal that will cause the timer be loaded with pre-defined value - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param sync_conf sync configuration on this timer - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_sync_configure(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_sync_config_t *sync_conf); - -/** - * @brief Disable sync submodule on given timer - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_sync_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num); - -/** - * @brief Set sync output on given timer - * Configures what event triggers MCPWM timer to output a sync signal. - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * @param trigger set the trigger that will cause the timer to generate a software sync signal. - * Specifically, `MCPWM_SWSYNC_SOURCE_DISABLED` will disable the timer from generating sync signal. - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Parameter error - */ -esp_err_t mcpwm_set_timer_sync_output(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_timer_sync_trigger_t trigger); - -/** - * @brief Trigger a software sync event and sends it to a specific timer. - * - * @param mcpwm_num set MCPWM unit - * @param timer_num set timer number(0-2) of MCPWM, each MCPWM unit has 3 timers - * - * @note This software sync event will have the same effect as hw one, except that: - * - On esp32s3 the soft sync event can be routed to its output if `MCPWM_SWSYNC_SOURCE_SYNCIN` is selected via `mcpwm_set_timer_sync_output()` - * - On esp32 there is no such behavior and soft sync event will only take effect on this timer and can not be propagated to others. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Function pointer error. - */ -esp_err_t mcpwm_timer_trigger_soft_sync(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num); - -/** - * @brief Set external GPIO sync input inverter - * - * @param mcpwm_num set MCPWM unit - * @param sync_sig set sync signal of MCPWM, only supports GPIO sync signal - * @param invert whether GPIO sync source input is inverted (to get negative edge trigger) - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG Function pointer error. - */ -esp_err_t mcpwm_sync_invert_gpio_synchro(mcpwm_unit_t mcpwm_num, mcpwm_sync_signal_t sync_sig, bool invert); - -#ifdef __cplusplus -} -#endif diff --git a/components/driver/deprecated/driver/mcpwm_types_legacy.h b/components/driver/deprecated/driver/mcpwm_types_legacy.h deleted file mode 100644 index a93ab83547..0000000000 --- a/components/driver/deprecated/driver/mcpwm_types_legacy.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include -#include -#include "esp_bit_defs.h" -#include "soc/soc_caps.h" -#include "hal/mcpwm_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief IO signals for the MCPWM - * - * - 6 MCPWM output pins that generate PWM signals - * - 3 MCPWM fault input pins to detect faults like over-current, over-voltage, etc. - * - 3 MCPWM sync input pins to synchronize MCPWM outputs signals - * - 3 MCPWM capture input pins to gather feedback from controlled motors, using e.g. hall sensors - */ -typedef enum { - MCPWM0A = 0, /*! 1 - MCPWM_UNIT_1, /*! -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_log.h" -#include "esp_err.h" -#include "esp_check.h" -#include "esp_rom_gpio.h" -#include "esp_intr_alloc.h" -#include "soc/mcpwm_periph.h" -#include "soc/io_mux_reg.h" -#include "soc/soc_caps.h" -#include "hal/mcpwm_hal.h" -#include "hal/gpio_hal.h" -#include "hal/mcpwm_ll.h" -#include "driver/mcpwm_types_legacy.h" -#include "driver/gpio.h" -#include "esp_private/periph_ctrl.h" -#include "esp_private/gpio.h" -#include "esp_private/esp_clk.h" -#include "esp_private/esp_clk_tree_common.h" -#include "esp_clk_tree.h" - -static const char *TAG = "mcpwm(legacy)"; - -_Static_assert(MCPWM_UNIT_MAX == SOC_MCPWM_GROUPS, "MCPWM unit number not equal to chip capabilities"); - -#define MCPWM_DRIVER_INIT_ERROR "MCPWM DRIVER NOT INITIALIZED" -#define MCPWM_GROUP_NUM_ERROR "MCPWM GROUP NUM ERROR" -#define MCPWM_PRESCALE_ERROR "MCPWM PRESCALE ERROR" -#define MCPWM_TIMER_ERROR "MCPWM TIMER NUM ERROR" -#define MCPWM_CAPTURE_ERROR "MCPWM CAPTURE NUM ERROR" -#define MCPWM_PARAM_ADDR_ERROR "MCPWM PARAM ADDR ERROR" -#define MCPWM_DUTY_TYPE_ERROR "MCPWM DUTY TYPE ERROR" -#define MCPWM_GPIO_ERROR "MCPWM GPIO NUM ERROR" -#define MCPWM_GEN_ERROR "MCPWM GENERATOR ERROR" -#define MCPWM_DT_ERROR "MCPWM DEADTIME TYPE ERROR" -#define MCPWM_CAP_EXIST_ERROR "MCPWM USER CAP INT SERVICE ALREADY EXISTS" - -#ifdef CONFIG_MCPWM_ISR_IRAM_SAFE -#define MCPWM_ISR_ATTR IRAM_ATTR -#define MCPWM_INTR_FLAG ESP_INTR_FLAG_IRAM -#else -#define MCPWM_ISR_ATTR -#define MCPWM_INTR_FLAG 0 -#endif - -#if SOC_PERIPH_CLK_CTRL_SHARED -#define MCPWM_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() -#else -#define MCPWM_CLOCK_SRC_ATOMIC() -#endif - -#if !SOC_RCC_IS_INDEPENDENT -#define MCPWM_RCC_ATOMIC() PERIPH_RCC_ATOMIC() -#else -#define MCPWM_RCC_ATOMIC() -#endif - -// Note: we can't modify the default MCPWM group resolution once it's determined -// otherwise we may break user's existing code which configures the dead-time based on this resolution, see `mcpwm_deadtime_enable` -#if CONFIG_IDF_TARGET_ESP32H2 -#define MCPWM_DEFAULT_GROUP_CLK_RESOLUTION_HZ (12 * 1000 * 1000) -#else -#define MCPWM_DEFAULT_GROUP_CLK_RESOLUTION_HZ (10 * 1000 * 1000) -#endif - -// Preset MCPWM Timer clock resolution (1MHz) -#define MCPWM_DEFAULT_TIMER_CLK_RESOLUTION_HZ (1 * 1000 * 1000) - -ESP_STATIC_ASSERT(SOC_MCPWM_OPERATORS_PER_GROUP >= SOC_MCPWM_TIMERS_PER_GROUP, "This driver assumes the timer num equals to the operator num."); -ESP_STATIC_ASSERT(SOC_MCPWM_COMPARATORS_PER_OPERATOR >= SOC_MCPWM_GENERATORS_PER_OPERATOR, "This driver assumes the generator num equals to the generator num."); -ESP_STATIC_ASSERT(SOC_MCPWM_GENERATORS_PER_OPERATOR == 2, "This driver assumes the generator num equals to 2."); - -#define MCPWM_TIMER_ID_CHECK(mcpwm_num, timer_num) \ - do { \ - ESP_RETURN_ON_FALSE((mcpwm_num) < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR); \ - ESP_RETURN_ON_FALSE((timer_num) < SOC_MCPWM_TIMERS_PER_GROUP, ESP_ERR_INVALID_ARG, TAG, MCPWM_TIMER_ERROR); \ - } while (0) - -#define MCPWM_TIMER_CHECK(mcpwm_num, timer_num) \ - do { \ - MCPWM_TIMER_ID_CHECK(mcpwm_num, timer_num); \ - ESP_RETURN_ON_FALSE(context[mcpwm_num].hal.dev, ESP_ERR_INVALID_STATE, TAG, MCPWM_DRIVER_INIT_ERROR); \ - } while (0) - -#define MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen) \ - do { \ - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); \ - ESP_RETURN_ON_FALSE((gen) < MCPWM_GEN_MAX, ESP_ERR_INVALID_ARG, TAG, MCPWM_GEN_ERROR); \ - } while (0) - -typedef struct { - cap_isr_cb_t fn; // isr function - void *args; // isr function args -} cap_isr_func_t; - -typedef struct { - mcpwm_hal_context_t hal; - portMUX_TYPE spinlock; - _lock_t mutex_lock; - const int group_id; - int group_resolution_hz; - int timer_resolution_hz[SOC_MCPWM_TIMERS_PER_GROUP]; - intr_handle_t mcpwm_intr_handle; // handler for ISR register, one per MCPWM group - cap_isr_func_t cap_isr_func[SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER]; // handler for ISR callback, one for each cap ch - int module_ref_count; -} mcpwm_context_t; - -static mcpwm_context_t context[SOC_MCPWM_GROUPS] = { - [0] = { - .hal = {MCPWM_LL_GET_HW(0)}, - .spinlock = portMUX_INITIALIZER_UNLOCKED, - .group_id = 0, - }, -#if SOC_MCPWM_GROUPS > 1 - [1] = { - .hal = {MCPWM_LL_GET_HW(1)}, - .spinlock = portMUX_INITIALIZER_UNLOCKED, - .group_id = 1, - }, -#endif -}; - -typedef void (*mcpwm_ll_gen_set_event_action_t)(mcpwm_dev_t *mcpwm, int op, int gen, int action); - -static inline void mcpwm_critical_enter(mcpwm_unit_t mcpwm_num) -{ - portENTER_CRITICAL(&context[mcpwm_num].spinlock); -} - -static inline void mcpwm_critical_exit(mcpwm_unit_t mcpwm_num) -{ - portEXIT_CRITICAL(&context[mcpwm_num].spinlock); -} - -static inline void mcpwm_mutex_lock(mcpwm_unit_t mcpwm_num) -{ - _lock_acquire(&context[mcpwm_num].mutex_lock); -} - -static inline void mcpwm_mutex_unlock(mcpwm_unit_t mcpwm_num) -{ - _lock_release(&context[mcpwm_num].mutex_lock); -} - -static void mcpwm_module_enable(mcpwm_unit_t mcpwm_num) -{ - mcpwm_critical_enter(mcpwm_num); - if (context[mcpwm_num].module_ref_count == 0) { - MCPWM_RCC_ATOMIC() { - mcpwm_ll_enable_bus_clock(mcpwm_num, true); - mcpwm_ll_reset_register(mcpwm_num); - } - MCPWM_CLOCK_SRC_ATOMIC() { - mcpwm_ll_group_enable_clock(mcpwm_num, true); - } - } - context[mcpwm_num].module_ref_count++; - mcpwm_critical_exit(mcpwm_num); -} - -static void mcpwm_module_disable(mcpwm_unit_t mcpwm_num) -{ - mcpwm_critical_enter(mcpwm_num); - context[mcpwm_num].module_ref_count--; - if (context[mcpwm_num].module_ref_count == 0) { - MCPWM_RCC_ATOMIC() { - mcpwm_ll_enable_bus_clock(mcpwm_num, false); - } - MCPWM_CLOCK_SRC_ATOMIC() { - mcpwm_ll_group_enable_clock(mcpwm_num, false); - } - } - mcpwm_critical_exit(mcpwm_num); -} - -esp_err_t mcpwm_gpio_init(mcpwm_unit_t mcpwm_num, mcpwm_io_signals_t io_signal, int gpio_num) -{ - if (gpio_num < 0) { // ignore on minus gpio number - return ESP_OK; - } - - ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, MCPWM_GPIO_ERROR); - - if (io_signal <= MCPWM2B) { // Generator output signal - ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, MCPWM_GPIO_ERROR); - gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT); - int operator_id = io_signal / 2; - int generator_id = io_signal % 2; - esp_rom_gpio_connect_out_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].operators[operator_id].generators[generator_id].pwm_sig, 0, 0); - } else if (io_signal <= MCPWM_SYNC_2) { // External sync input signal - gpio_set_direction(gpio_num, GPIO_MODE_INPUT); - int gpio_sync_id = io_signal - MCPWM_SYNC_0; - esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].gpio_synchros[gpio_sync_id].sync_sig, 0); - } else if (io_signal <= MCPWM_FAULT_2) { // Fault input signal - gpio_set_direction(gpio_num, GPIO_MODE_INPUT); - int fault_id = io_signal - MCPWM_FAULT_0; - esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].gpio_faults[fault_id].fault_sig, 0); - } else if (io_signal >= MCPWM_CAP_0 && io_signal <= MCPWM_CAP_2) { // Capture input signal - gpio_set_direction(gpio_num, GPIO_MODE_INPUT); - int capture_id = io_signal - MCPWM_CAP_0; - esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].captures[capture_id].cap_sig, 0); - } - gpio_func_sel(gpio_num, PIN_FUNC_GPIO); - return ESP_OK; -} - -esp_err_t mcpwm_set_pin(mcpwm_unit_t mcpwm_num, const mcpwm_pin_config_t *mcpwm_pin) -{ - ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR); - mcpwm_gpio_init(mcpwm_num, MCPWM0A, mcpwm_pin->mcpwm0a_out_num); //MCPWM0A - mcpwm_gpio_init(mcpwm_num, MCPWM0B, mcpwm_pin->mcpwm0b_out_num); //MCPWM0B - mcpwm_gpio_init(mcpwm_num, MCPWM1A, mcpwm_pin->mcpwm1a_out_num); //MCPWM1A - mcpwm_gpio_init(mcpwm_num, MCPWM1B, mcpwm_pin->mcpwm1b_out_num); //MCPWM1B - mcpwm_gpio_init(mcpwm_num, MCPWM2A, mcpwm_pin->mcpwm2a_out_num); //MCPWM2A - mcpwm_gpio_init(mcpwm_num, MCPWM2B, mcpwm_pin->mcpwm2b_out_num); //MCPWM2B - mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_0, mcpwm_pin->mcpwm_sync0_in_num); //SYNC0 - mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_1, mcpwm_pin->mcpwm_sync1_in_num); //SYNC1 - mcpwm_gpio_init(mcpwm_num, MCPWM_SYNC_2, mcpwm_pin->mcpwm_sync2_in_num); //SYNC2 - mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_0, mcpwm_pin->mcpwm_fault0_in_num); //FAULT0 - mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_1, mcpwm_pin->mcpwm_fault1_in_num); //FAULT1 - mcpwm_gpio_init(mcpwm_num, MCPWM_FAULT_2, mcpwm_pin->mcpwm_fault2_in_num); //FAULT2 - mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_0, mcpwm_pin->mcpwm_cap0_in_num); //CAP0 - mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_1, mcpwm_pin->mcpwm_cap1_in_num); //CAP1 - mcpwm_gpio_init(mcpwm_num, MCPWM_CAP_2, mcpwm_pin->mcpwm_cap2_in_num); //CAP2 - return ESP_OK; -} - -esp_err_t mcpwm_start(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num) -{ - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_timer_set_start_stop_command(context[mcpwm_num].hal.dev, timer_num, MCPWM_TIMER_START_NO_STOP); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_stop(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num) -{ - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_timer_set_start_stop_command(context[mcpwm_num].hal.dev, timer_num, MCPWM_TIMER_STOP_EMPTY); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -static inline uint32_t mcpwm_group_get_resolution(mcpwm_unit_t mcpwm_num) -{ - if (context[mcpwm_num].group_resolution_hz == 0) { - context[mcpwm_num].group_resolution_hz = MCPWM_DEFAULT_GROUP_CLK_RESOLUTION_HZ; - } - return context[mcpwm_num].group_resolution_hz; -} - -static inline uint32_t mcpwm_timer_get_resolution(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num) -{ - if (context[mcpwm_num].timer_resolution_hz[timer_num] == 0) { - context[mcpwm_num].timer_resolution_hz[timer_num] = MCPWM_DEFAULT_TIMER_CLK_RESOLUTION_HZ; - } - return context[mcpwm_num].timer_resolution_hz[timer_num]; -} - -esp_err_t mcpwm_group_set_resolution(mcpwm_unit_t mcpwm_num, uint32_t resolution) -{ - mcpwm_module_enable(mcpwm_num); - uint32_t clk_src_hz = 0; - esp_clk_tree_src_get_freq_hz(MCPWM_TIMER_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz); - - int pre_scale_temp = clk_src_hz / resolution; - ESP_RETURN_ON_FALSE(pre_scale_temp >= 1, ESP_ERR_INVALID_ARG, TAG, "invalid resolution"); - context[mcpwm_num].group_resolution_hz = clk_src_hz / pre_scale_temp; - - MCPWM_CLOCK_SRC_ATOMIC() { - mcpwm_ll_group_set_clock_prescale(mcpwm_num, pre_scale_temp); - } - return ESP_OK; -} - -esp_err_t mcpwm_timer_set_resolution(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint32_t resolution) -{ - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - uint32_t group_resolution = mcpwm_group_get_resolution(mcpwm_num); - - int pre_scale_temp = group_resolution / resolution; - ESP_RETURN_ON_FALSE(pre_scale_temp >= 1, ESP_ERR_INVALID_ARG, TAG, "invalid resolution"); - context[mcpwm_num].timer_resolution_hz[timer_num] = context[mcpwm_num].group_resolution_hz / pre_scale_temp; - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_timer_set_clock_prescale(hal->dev, timer_num, pre_scale_temp); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_set_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint32_t frequency) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - mcpwm_critical_enter(mcpwm_num); - - mcpwm_ll_timer_update_period_at_once(hal->dev, timer_num); - uint32_t previous_peak = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false); - uint32_t timer_resolution = mcpwm_timer_get_resolution(mcpwm_num, timer_num); - uint32_t new_peak = timer_resolution / frequency; - mcpwm_ll_timer_set_peak(hal->dev, timer_num, new_peak, false); - // keep the duty cycle unchanged - float scale = ((float)new_peak) / previous_peak; - // the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output - uint32_t previous_cmp_a = mcpwm_ll_operator_get_compare_value(hal->dev, op, 0); - uint32_t previous_cmp_b = mcpwm_ll_operator_get_compare_value(hal->dev, op, 1); - // update compare value immediately - mcpwm_ll_operator_update_compare_at_once(hal->dev, op, 0); - mcpwm_ll_operator_update_compare_at_once(hal->dev, op, 1); - mcpwm_ll_operator_set_compare_value(hal->dev, op, 0, (uint32_t)(previous_cmp_a * scale)); - mcpwm_ll_operator_set_compare_value(hal->dev, op, 1, (uint32_t)(previous_cmp_b * scale)); - - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_set_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, float duty) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output - const int cmp = gen; - MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - mcpwm_critical_enter(mcpwm_num); - uint32_t set_duty = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false) * duty / 100; - mcpwm_ll_operator_set_compare_value(hal->dev, op, cmp, set_duty); - mcpwm_ll_operator_enable_update_compare_on_tez(hal->dev, op, cmp, true); - mcpwm_ll_operator_enable_update_compare_on_tep(hal->dev, op, cmp, true); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_set_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, uint32_t duty_in_us) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output - const int cmp = gen; - MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - mcpwm_critical_enter(mcpwm_num); - // to avid multiplication overflow, use uint64_t here - uint64_t timer_resolution = mcpwm_timer_get_resolution(mcpwm_num, timer_num); - uint64_t compare_val = timer_resolution * duty_in_us / 1000000; - mcpwm_ll_operator_set_compare_value(hal->dev, op, cmp, (uint32_t)compare_val); - mcpwm_ll_operator_enable_update_compare_on_tez(hal->dev, op, cmp, true); - mcpwm_ll_operator_enable_update_compare_on_tep(hal->dev, op, cmp, true); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_set_duty_type(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen, - mcpwm_duty_type_t duty_type) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - MCPWM_GEN_CHECK(mcpwm_num, timer_num, gen); - ESP_RETURN_ON_FALSE(duty_type < MCPWM_DUTY_MODE_MAX, ESP_ERR_INVALID_ARG, TAG, MCPWM_DUTY_TYPE_ERROR); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - //the driver currently always use the comparator A for PWMxA output, and comparator B for PWMxB output - mcpwm_critical_enter(mcpwm_num); - switch (mcpwm_ll_timer_get_count_mode(hal->dev, timer_num)) { - case MCPWM_TIMER_COUNT_MODE_UP: - if (duty_type == MCPWM_DUTY_MODE_0) { - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_HIGH); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_GEN_ACTION_KEEP); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_LOW); - } else if (duty_type == MCPWM_DUTY_MODE_1) { - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_GEN_ACTION_LOW); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_NO_CHANGE); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_HIGH); - } else if (duty_type == MCPWM_DUTY_MODE_FORCE_LOW) { - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_LOW); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_LOW); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_LOW); - } else if (duty_type == MCPWM_DUTY_MODE_FORCE_HIGH) { - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_HIGH); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_HIGH); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_HIGH); - } - break; - case MCPWM_TIMER_COUNT_MODE_DOWN: - if (duty_type == MCPWM_DUTY_MODE_0) { - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_LOW); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_NO_CHANGE); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_HIGH); - } else if (duty_type == MCPWM_DUTY_MODE_1) { - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_HIGH); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_NO_CHANGE); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_LOW); - } else if (duty_type == MCPWM_DUTY_MODE_FORCE_LOW) { - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_LOW); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_LOW); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_LOW); - } else if (duty_type == MCPWM_DUTY_MODE_FORCE_HIGH) { - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_HIGH); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_HIGH); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_HIGH); - } - break; - case MCPWM_TIMER_COUNT_MODE_UP_DOWN: - if (duty_type == MCPWM_DUTY_MODE_0) { - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_HIGH); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_LOW); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_HIGH); - } else if (duty_type == MCPWM_DUTY_MODE_1) { - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_LOW); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_HIGH); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_LOW); - } else if (duty_type == MCPWM_DUTY_MODE_FORCE_LOW) { - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_LOW); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_LOW); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_LOW); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_LOW); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_LOW); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_LOW); - } else if (duty_type == MCPWM_DUTY_MODE_FORCE_HIGH) { - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_HIGH); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_HIGH); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_EMPTY, MCPWM_ACTION_FORCE_HIGH); - mcpwm_ll_generator_set_action_on_timer_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, MCPWM_TIMER_EVENT_FULL, MCPWM_ACTION_FORCE_HIGH); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_DOWN, gen, MCPWM_ACTION_FORCE_HIGH); - mcpwm_ll_generator_set_action_on_compare_event(hal->dev, op, gen, MCPWM_TIMER_DIRECTION_UP, gen, MCPWM_ACTION_FORCE_HIGH); - } - break; - default: - break; - } - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_config_t *mcpwm_conf) -{ - const int op = timer_num; - MCPWM_TIMER_ID_CHECK(mcpwm_num, op); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - mcpwm_module_enable(mcpwm_num); - mcpwm_hal_init_config_t config = { - .group_id = mcpwm_num - }; - mcpwm_hal_init(hal, &config); - - uint32_t clk_src_hz = 0; - esp_clk_tree_src_get_freq_hz(MCPWM_TIMER_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz); - uint32_t group_resolution = mcpwm_group_get_resolution(mcpwm_num); - uint32_t timer_resolution = mcpwm_timer_get_resolution(mcpwm_num, timer_num); - uint32_t group_pre_scale = clk_src_hz / group_resolution; - uint32_t timer_pre_scale = group_resolution / timer_resolution; - - ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, true)); - MCPWM_CLOCK_SRC_ATOMIC() { - mcpwm_ll_group_set_clock_source(mcpwm_num, (soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT); - mcpwm_ll_group_set_clock_prescale(mcpwm_num, group_pre_scale); - } - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_timer_set_clock_prescale(hal->dev, timer_num, timer_pre_scale); - mcpwm_ll_timer_set_count_mode(hal->dev, timer_num, mcpwm_conf->counter_mode); - mcpwm_ll_timer_update_period_at_once(hal->dev, timer_num); - mcpwm_ll_timer_set_peak(hal->dev, timer_num, timer_resolution / mcpwm_conf->frequency, false); - mcpwm_ll_operator_connect_timer(hal->dev, timer_num, timer_num); //the driver currently always use the timer x for operator x - mcpwm_critical_exit(mcpwm_num); - - mcpwm_set_duty(mcpwm_num, timer_num, 0, mcpwm_conf->cmpr_a); - mcpwm_set_duty(mcpwm_num, timer_num, 1, mcpwm_conf->cmpr_b); - mcpwm_set_duty_type(mcpwm_num, timer_num, 0, mcpwm_conf->duty_mode); - mcpwm_set_duty_type(mcpwm_num, timer_num, 1, mcpwm_conf->duty_mode); - mcpwm_start(mcpwm_num, timer_num); - - return ESP_OK; -} - -uint32_t mcpwm_get_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num) -{ - if (mcpwm_num >= MCPWM_UNIT_MAX || timer_num >= MCPWM_TIMER_MAX) { - ESP_LOGE(TAG, "Invalid MCPWM timer instance"); - return 0; - } - - uint32_t timer_resolution = mcpwm_timer_get_resolution(mcpwm_num, timer_num); - - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - mcpwm_critical_enter(mcpwm_num); - uint32_t peak = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false); - uint32_t freq = timer_resolution / peak; - mcpwm_critical_exit(mcpwm_num); - return freq; -} - -float mcpwm_get_duty(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen) -{ - if (mcpwm_num >= MCPWM_UNIT_MAX || timer_num >= MCPWM_TIMER_MAX || gen >= MCPWM_GEN_MAX) { - ESP_LOGE(TAG, "Invalid MCPWM generator instance"); - return 0; - } - //the driver currently always use the timer x for operator x - const int op = timer_num; - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - mcpwm_critical_enter(mcpwm_num); - float duty = 100.0 * mcpwm_ll_operator_get_compare_value(hal->dev, op, gen) / mcpwm_ll_timer_get_peak(hal->dev, timer_num, false); - mcpwm_critical_exit(mcpwm_num); - return duty; -} - -uint32_t mcpwm_get_duty_in_us(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_operator_t gen) -{ - if (mcpwm_num >= MCPWM_UNIT_MAX || timer_num >= MCPWM_TIMER_MAX || gen >= MCPWM_GEN_MAX) { - ESP_LOGE(TAG, "Invalid MCPWM generator instance"); - return 0; - } - - uint32_t timer_resolution = mcpwm_timer_get_resolution(mcpwm_num, timer_num); - - //the driver currently always use the timer x for operator x - const int op = timer_num; - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - mcpwm_critical_enter(mcpwm_num); - uint32_t duty = mcpwm_ll_operator_get_compare_value(hal->dev, op, gen) * (1000000.0 / timer_resolution); - mcpwm_critical_exit(mcpwm_num); - return duty; -} - -esp_err_t mcpwm_set_signal_high(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen) -{ - //the driver currently always use the timer x for operator x - return mcpwm_set_duty_type(mcpwm_num, timer_num, gen, MCPWM_DUTY_MODE_FORCE_HIGH); -} - -esp_err_t mcpwm_set_signal_low(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_generator_t gen) -{ - //the driver currently always use the timer x for operator x - return mcpwm_set_duty_type(mcpwm_num, timer_num, gen, MCPWM_DUTY_MODE_FORCE_LOW); -} - -esp_err_t mcpwm_carrier_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_carrier_enable(context[mcpwm_num].hal.dev, op, true); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_carrier_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_carrier_enable(context[mcpwm_num].hal.dev, op, false); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_carrier_set_period(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_period) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_carrier_set_prescale(context[mcpwm_num].hal.dev, op, carrier_period + 1); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_carrier_set_duty_cycle(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t carrier_duty) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_carrier_set_duty(context[mcpwm_num].hal.dev, op, carrier_duty); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_carrier_oneshot_mode_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, uint8_t pulse_width) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_carrier_set_first_pulse_width(context[mcpwm_num].hal.dev, op, pulse_width + 1); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_carrier_output_invert(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, - mcpwm_carrier_out_ivt_t carrier_ivt_mode) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_carrier_out_invert(context[mcpwm_num].hal.dev, op, carrier_ivt_mode); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_carrier_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_carrier_config_t *carrier_conf) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - mcpwm_carrier_enable(mcpwm_num, timer_num); - mcpwm_carrier_set_period(mcpwm_num, timer_num, carrier_conf->carrier_period); - mcpwm_carrier_set_duty_cycle(mcpwm_num, timer_num, carrier_conf->carrier_duty); - mcpwm_carrier_oneshot_mode_enable(mcpwm_num, timer_num, carrier_conf->pulse_width_in_os); - mcpwm_carrier_output_invert(mcpwm_num, timer_num, carrier_conf->carrier_ivt_mode); - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_carrier_in_invert(hal->dev, op, false); - mcpwm_critical_exit(mcpwm_num); - - return ESP_OK; -} - -esp_err_t mcpwm_deadtime_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_deadtime_type_t dt_mode, - uint32_t red, uint32_t fed) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - ESP_RETURN_ON_FALSE(dt_mode < MCPWM_DEADTIME_TYPE_MAX, ESP_ERR_INVALID_ARG, TAG, MCPWM_DT_ERROR); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_deadtime_enable_update_delay_on_tez(hal->dev, op, true); - // The dead time delay unit equals to MCPWM group resolution - mcpwm_ll_operator_set_deadtime_clock_src(hal->dev, op, MCPWM_LL_DEADTIME_CLK_SRC_GROUP); - mcpwm_ll_deadtime_set_rising_delay(hal->dev, op, red + 1); - mcpwm_ll_deadtime_set_falling_delay(hal->dev, op, fed + 1); - switch (dt_mode) { - case MCPWM_BYPASS_RED: - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0 - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, true); // S1=1 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2=0 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0 - mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0 - mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5=0 - break; - case MCPWM_BYPASS_FED: - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, true); // S0=1 - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false); // S1=0 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2=0 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0 - mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0 - mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5=0 - break; - case MCPWM_ACTIVE_HIGH_MODE: - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0 - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false); // S1=0 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2=0 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0 - mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0 - mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5=0 - break; - case MCPWM_ACTIVE_LOW_MODE: - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0 - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false); // S1=0 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, true); // S2=1 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, true); // S3=1 - mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0 - mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5=0 - break; - case MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE: - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0 - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false); // S1=0 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2=0 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, true); // S3=1 - mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0 - mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5=0 - break; - case MCPWM_ACTIVE_LOW_COMPLIMENT_MODE: - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0 - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, false); // S1=0 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, true); // S2=1 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0 - mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0 - mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5=0 - break; - case MCPWM_ACTIVE_RED_FED_FROM_PWMXA: - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0 - mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4=0 - mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 0, true); // S6=1 - mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 1, false); // S7=0 - mcpwm_ll_deadtime_enable_deb(hal->dev, op, true); // S8=1 - break; - case MCPWM_ACTIVE_RED_FED_FROM_PWMXB: - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, false); // S0=0 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3=0 - mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 1); // S4=1 - mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 0, true); // S6=1 - mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 1, false); // S7=0 - mcpwm_ll_deadtime_enable_deb(hal->dev, op, true); // S8=1 - break; - default : - break; - } - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_deadtime_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 1, true); // S0 - mcpwm_ll_deadtime_bypass_path(hal->dev, op, 0, true); // S1 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 0, false); // S2 - mcpwm_ll_deadtime_invert_outpath(hal->dev, op, 1, false); // S3 - mcpwm_ll_deadtime_red_select_generator(hal->dev, op, 0); // S4 - mcpwm_ll_deadtime_fed_select_generator(hal->dev, op, 0); // S5 - mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 0, false); // S6 - mcpwm_ll_deadtime_swap_out_path(hal->dev, op, 1, false); // S7 - mcpwm_ll_deadtime_enable_deb(hal->dev, op, false); // S8 - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_fault_init(mcpwm_unit_t mcpwm_num, mcpwm_fault_input_level_t intput_level, mcpwm_fault_signal_t fault_sig) -{ - ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_fault_enable_detection(hal->dev, fault_sig, true); - mcpwm_ll_fault_set_active_level(hal->dev, fault_sig, intput_level); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_fault_deinit(mcpwm_unit_t mcpwm_num, mcpwm_fault_signal_t fault_sig) -{ - ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_fault_enable_detection(hal->dev, fault_sig, false); - for (int i = 0; i < SOC_MCPWM_OPERATORS_PER_GROUP; i++) { - mcpwm_ll_brake_clear_ost(hal->dev, i); // make sure operator has exit the ost fault state totally - } - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_fault_set_cyc_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig, - mcpwm_output_action_t action_on_pwmxa, mcpwm_output_action_t action_on_pwmxb) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - MCPWM_TIMER_CHECK(mcpwm_num, op); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_brake_enable_cbc_mode(hal->dev, op, fault_sig, true); - mcpwm_ll_brake_enable_cbc_refresh_on_tez(hal->dev, op, true); - mcpwm_ll_brake_enable_oneshot_mode(hal->dev, op, fault_sig, false); - mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_OPER_BRAKE_MODE_CBC, action_on_pwmxa); - mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_UP, MCPWM_OPER_BRAKE_MODE_CBC, action_on_pwmxa); - mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_OPER_BRAKE_MODE_CBC, action_on_pwmxb); - mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_UP, MCPWM_OPER_BRAKE_MODE_CBC, action_on_pwmxb); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_fault_set_oneshot_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_fault_signal_t fault_sig, - mcpwm_action_on_pwmxa_t action_on_pwmxa, mcpwm_action_on_pwmxb_t action_on_pwmxb) -{ - //the driver currently always use the timer x for operator x - const int op = timer_num; - MCPWM_TIMER_CHECK(mcpwm_num, op); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_brake_clear_ost(hal->dev, op); - mcpwm_ll_brake_enable_oneshot_mode(hal->dev, op, fault_sig, true); - mcpwm_ll_brake_enable_cbc_mode(hal->dev, op, fault_sig, false); - mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_OPER_BRAKE_MODE_OST, action_on_pwmxa); - mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_UP, MCPWM_OPER_BRAKE_MODE_OST, action_on_pwmxa); - mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_OPER_BRAKE_MODE_OST, action_on_pwmxb); - mcpwm_ll_generator_set_action_on_brake_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_UP, MCPWM_OPER_BRAKE_MODE_OST, action_on_pwmxb); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -static void MCPWM_ISR_ATTR mcpwm_default_isr_handler(void *arg) -{ - mcpwm_context_t *curr_context = (mcpwm_context_t *) arg; - uint32_t intr_status = mcpwm_ll_intr_get_capture_status(curr_context->hal.dev); - mcpwm_ll_intr_clear_capture_status(curr_context->hal.dev, intr_status); - bool need_yield = false; - for (int i = 0; i < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER; ++i) { - if ((intr_status >> i) & 0x1) { - if (curr_context->cap_isr_func[i].fn != NULL) { - cap_event_data_t edata; - edata.cap_edge = mcpwm_ll_capture_get_edge(curr_context->hal.dev, i) == MCPWM_CAP_EDGE_NEG ? MCPWM_NEG_EDGE - : MCPWM_POS_EDGE; - edata.cap_value = mcpwm_ll_capture_get_value(curr_context->hal.dev, i); - if (curr_context->cap_isr_func[i].fn(curr_context->group_id, i, &edata, - curr_context->cap_isr_func[i].args)) { - need_yield = true; - } - } - } - } - if (need_yield) { - portYIELD_FROM_ISR(); - } -} - -esp_err_t mcpwm_capture_enable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_channel_id_t cap_channel, const mcpwm_capture_config_t *cap_conf) -{ - ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(cap_channel < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR); - ESP_RETURN_ON_FALSE(context[mcpwm_num].cap_isr_func[cap_channel].fn == NULL, ESP_ERR_INVALID_STATE, TAG, - MCPWM_CAP_EXIST_ERROR); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - // enable MCPWM module in case user don't use `mcpwm_init` at all. always increase reference count - mcpwm_module_enable(mcpwm_num); - - mcpwm_hal_init_config_t init_config = { - .group_id = mcpwm_num - }; - mcpwm_hal_init(hal, &init_config); - - uint32_t clk_src_hz = 0; - esp_clk_tree_src_get_freq_hz(MCPWM_TIMER_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_hz); - uint32_t group_resolution = mcpwm_group_get_resolution(mcpwm_num); - uint32_t group_pre_scale = clk_src_hz / group_resolution; - - ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, true)); - MCPWM_CLOCK_SRC_ATOMIC() { - mcpwm_ll_group_set_clock_source(mcpwm_num, (soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT); - mcpwm_ll_group_set_clock_prescale(mcpwm_num, group_pre_scale); - } - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_capture_enable_timer(hal->dev, true); - mcpwm_ll_capture_enable_channel(hal->dev, cap_channel, true); - 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 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); - - mcpwm_mutex_lock(mcpwm_num); - context[mcpwm_num].cap_isr_func[cap_channel].fn = cap_conf->capture_cb; - context[mcpwm_num].cap_isr_func[cap_channel].args = cap_conf->user_data; - esp_err_t ret = ESP_OK; - if (context[mcpwm_num].mcpwm_intr_handle == NULL) { - ret = esp_intr_alloc(mcpwm_periph_signals.groups[mcpwm_num].irq_id, MCPWM_INTR_FLAG, - mcpwm_default_isr_handler, - (void *)(context + mcpwm_num), &(context[mcpwm_num].mcpwm_intr_handle)); - } - mcpwm_mutex_unlock(mcpwm_num); - - return ret; -} - -esp_err_t mcpwm_capture_disable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_channel_id_t cap_channel) -{ - ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR); - ESP_RETURN_ON_FALSE(cap_channel < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR); - - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_capture_enable_channel(hal->dev, cap_channel, false); - mcpwm_ll_intr_enable(hal->dev, MCPWM_LL_EVENT_CAPTURE(cap_channel), false); - mcpwm_critical_exit(mcpwm_num); - ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, false)); - - mcpwm_mutex_lock(mcpwm_num); - context[mcpwm_num].cap_isr_func[cap_channel].fn = NULL; - context[mcpwm_num].cap_isr_func[cap_channel].args = NULL; - // if all user defined ISR callback is disabled, free the handle - bool should_free_handle = true; - for (int i = 0; i < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER; ++i) { - if (context[mcpwm_num].cap_isr_func[i].fn != NULL) { - should_free_handle = false; - break; - } - } - esp_err_t ret = ESP_OK; - if (should_free_handle) { - ret = esp_intr_free(context[mcpwm_num].mcpwm_intr_handle); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "failed to free interrupt handle"); - } - context[mcpwm_num].mcpwm_intr_handle = NULL; - } - mcpwm_mutex_unlock(mcpwm_num); - - // always decrease reference count - mcpwm_module_disable(mcpwm_num); - return ret; -} - -uint32_t MCPWM_ISR_ATTR mcpwm_capture_signal_get_value(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig) -{ - if (mcpwm_num >= MCPWM_UNIT_MAX || cap_sig >= SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER) { - return 0; - } - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - return mcpwm_ll_capture_get_value(hal->dev, cap_sig); -} - -uint32_t mcpwm_capture_get_resolution(mcpwm_unit_t mcpwm_num) -{ - if (mcpwm_num >= MCPWM_UNIT_MAX) { - ESP_LOGE(TAG, "Invalid MCPWM instance"); - return 0; - } -#if SOC_MCPWM_CAPTURE_CLK_FROM_GROUP - return mcpwm_group_get_resolution(mcpwm_num); -#else - return esp_clk_apb_freq(); -#endif -} - -uint32_t MCPWM_ISR_ATTR mcpwm_capture_signal_get_edge(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig) -{ - if (mcpwm_num >= MCPWM_UNIT_MAX || cap_sig >= SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER) { - return 0; - } - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - return mcpwm_ll_capture_get_edge(hal->dev, cap_sig) == MCPWM_CAP_EDGE_NEG ? 2 : 1; -} - -esp_err_t mcpwm_sync_configure(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpwm_sync_config_t *sync_conf) -{ - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - ESP_RETURN_ON_FALSE(sync_conf->sync_sig <= MCPWM_SELECT_GPIO_SYNC2, ESP_ERR_INVALID_ARG, TAG, "invalid sync_sig"); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_timer_set_sync_phase_direction(hal->dev, timer_num, sync_conf->count_direction); - // sync TEP with current setting - uint32_t set_phase = 0; - set_phase = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false) * sync_conf->timer_val / 1000; - mcpwm_ll_timer_set_sync_phase_value(hal->dev, timer_num, set_phase); - if (sync_conf->sync_sig == MCPWM_SELECT_NO_INPUT) { - mcpwm_ll_timer_clear_sync_input(hal->dev, timer_num); - } else if (sync_conf->sync_sig <= MCPWM_SELECT_TIMER2_SYNC) { - mcpwm_ll_timer_set_timer_sync_input(hal->dev, timer_num, sync_conf->sync_sig - MCPWM_SELECT_TIMER0_SYNC); - } else { - mcpwm_ll_timer_set_gpio_sync_input(hal->dev, timer_num, sync_conf->sync_sig - MCPWM_SELECT_GPIO_SYNC0); - } - mcpwm_ll_timer_enable_sync_input(hal->dev, timer_num, true); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_sync_disable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num) -{ - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_timer_enable_sync_input(hal->dev, timer_num, false); - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -esp_err_t mcpwm_timer_trigger_soft_sync(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num) -{ - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_timer_trigger_soft_sync(hal->dev, timer_num); - mcpwm_critical_exit(mcpwm_num); - - return ESP_OK; -} - -esp_err_t mcpwm_sync_invert_gpio_synchro(mcpwm_unit_t mcpwm_num, mcpwm_sync_signal_t sync_sig, bool invert) -{ - ESP_RETURN_ON_FALSE(sync_sig >= MCPWM_SELECT_GPIO_SYNC0 && sync_sig <= MCPWM_SELECT_GPIO_SYNC2, - ESP_ERR_INVALID_ARG, TAG, "invalid sync sig"); - - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - mcpwm_critical_enter(mcpwm_num); - mcpwm_ll_invert_gpio_sync_input(hal->dev, sync_sig - MCPWM_SELECT_GPIO_SYNC0, invert); - mcpwm_critical_exit(mcpwm_num); - - return ESP_OK; -} - -esp_err_t mcpwm_set_timer_sync_output(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcpwm_timer_sync_trigger_t trigger) -{ - MCPWM_TIMER_CHECK(mcpwm_num, timer_num); - - mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; - mcpwm_critical_enter(mcpwm_num); - switch (trigger) { - case MCPWM_SWSYNC_SOURCE_SYNCIN: - mcpwm_ll_timer_propagate_input_sync(hal->dev, timer_num); - break; - case MCPWM_SWSYNC_SOURCE_TEZ: - mcpwm_ll_timer_sync_out_on_timer_event(hal->dev, timer_num, MCPWM_TIMER_EVENT_EMPTY); - break; - case MCPWM_SWSYNC_SOURCE_TEP: - mcpwm_ll_timer_sync_out_on_timer_event(hal->dev, timer_num, MCPWM_TIMER_EVENT_FULL); - break; - case MCPWM_SWSYNC_SOURCE_DISABLED: - default: - mcpwm_ll_timer_disable_sync_out(hal->dev, timer_num); - break; - } - mcpwm_critical_exit(mcpwm_num); - return ESP_OK; -} - -#if !CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK -/** - * @brief This function will be called during start up, to check that this legacy mcpwm driver is not running along with the new MCPWM driver - */ -__attribute__((constructor)) -static void check_mcpwm_driver_conflict(void) -{ - // This function was declared as weak here. The new MCPWM driver has the implementation. - // So if the new MCPWM driver is not linked in, then `mcpwm_acquire_group_handle()` should be NULL at runtime. - extern __attribute__((weak)) void *mcpwm_acquire_group_handle(int group_id); - if ((void *)mcpwm_acquire_group_handle != NULL) { - ESP_EARLY_LOGE(TAG, "CONFLICT! driver_ng is not allowed to be used with the legacy driver"); - abort(); - } - ESP_EARLY_LOGW(TAG, "legacy driver is deprecated, please migrate to `driver/mcpwm_prelude.h`"); -} -#endif //CONFIG_MCPWM_SKIP_LEGACY_CONFLICT_CHECK diff --git a/components/driver/test_apps/.build-test-rules.yml b/components/driver/test_apps/.build-test-rules.yml index 86bee22c20..24b5b11e0a 100644 --- a/components/driver/test_apps/.build-test-rules.yml +++ b/components/driver/test_apps/.build-test-rules.yml @@ -8,12 +8,6 @@ components/driver/test_apps/legacy_i2c_driver: temporary: false reason: disable target test for legacy i2c driver. -components/driver/test_apps/legacy_mcpwm_driver: - disable: - - if: SOC_MCPWM_SUPPORTED != 1 - depends_filepatterns: - - components/driver/deprecated/**/*mcpwm* - components/driver/test_apps/legacy_rmt_driver: disable: - if: SOC_RMT_SUPPORTED != 1 diff --git a/components/driver/test_apps/legacy_mcpwm_driver/CMakeLists.txt b/components/driver/test_apps/legacy_mcpwm_driver/CMakeLists.txt deleted file mode 100644 index 36966373c3..0000000000 --- a/components/driver/test_apps/legacy_mcpwm_driver/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# This is the project CMakeLists.txt file for the test subproject -cmake_minimum_required(VERSION 3.16) - -# "Trim" the build. Include the minimal set of components, main, and anything it depends on. -set(COMPONENTS main) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(legacy_mcpwm_driver_test) diff --git a/components/driver/test_apps/legacy_mcpwm_driver/README.md b/components/driver/test_apps/legacy_mcpwm_driver/README.md deleted file mode 100644 index fe35f9e4f5..0000000000 --- a/components/driver/test_apps/legacy_mcpwm_driver/README.md +++ /dev/null @@ -1,2 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/legacy_mcpwm_driver/main/CMakeLists.txt b/components/driver/test_apps/legacy_mcpwm_driver/main/CMakeLists.txt deleted file mode 100644 index bcdc50e5e6..0000000000 --- a/components/driver/test_apps/legacy_mcpwm_driver/main/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set(srcs "test_app_main.c" - "test_legacy_mcpwm.c") - -# In order for the cases defined by `TEST_CASE` to be linked into the final elf, -# the component can be registered as WHOLE_ARCHIVE -idf_component_register(SRCS ${srcs} - PRIV_REQUIRES unity esp_driver_pcnt driver - WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/legacy_mcpwm_driver/main/test_app_main.c b/components/driver/test_apps/legacy_mcpwm_driver/main/test_app_main.c deleted file mode 100644 index 036ad5b227..0000000000 --- a/components/driver/test_apps/legacy_mcpwm_driver/main/test_app_main.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "unity.h" -#include "unity_test_utils.h" -#include "esp_heap_caps.h" - -#define TEST_MEMORY_LEAK_THRESHOLD (300) - -static size_t before_free_8bit; -static size_t before_free_32bit; - -void setUp(void) -{ - before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); -} - -void tearDown(void) -{ - size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); - printf("\n"); - unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD); - unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD); -} - -void app_main(void) -{ - unity_run_menu(); -} diff --git a/components/driver/test_apps/legacy_mcpwm_driver/main/test_legacy_mcpwm.c b/components/driver/test_apps/legacy_mcpwm_driver/main/test_legacy_mcpwm.c deleted file mode 100644 index c9270b2459..0000000000 --- a/components/driver/test_apps/legacy_mcpwm_driver/main/test_legacy_mcpwm.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include "unity.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "soc/soc_caps.h" -#include "hal/gpio_hal.h" -#include "esp_rom_gpio.h" -#include "esp_private/esp_clk.h" -#include "esp_private/gpio.h" -#include "soc/mcpwm_periph.h" -#include "soc/io_mux_reg.h" -#include "driver/pulse_cnt.h" -#include "driver/mcpwm.h" -#include "driver/gpio.h" - -#if CONFIG_IDF_TARGET_ESP32 -#define TEST_PWMA_GPIO (2) -#define TEST_PWMB_GPIO (4) -#define TEST_CAP_GPIO (21) -#define TEST_FAULT_GPIO (21) -#define TEST_SYNC_GPIO_0 (21) -#define TEST_SYNC_GPIO_1 (18) -#define TEST_SYNC_GPIO_2 (19) -#elif CONFIG_IDF_TARGET_ESP32P4 -#define TEST_PWMA_GPIO (20) -#define TEST_PWMB_GPIO (21) -#define TEST_CAP_GPIO (22) -#define TEST_FAULT_GPIO (22) -#define TEST_SYNC_GPIO_0 (22) -#define TEST_SYNC_GPIO_1 (32) -#define TEST_SYNC_GPIO_2 (33) -#else -#define TEST_PWMA_GPIO (1) -#define TEST_PWMB_GPIO (2) -#define TEST_CAP_GPIO (3) -#define TEST_FAULT_GPIO (3) -#define TEST_SYNC_GPIO_0 (3) -#define TEST_SYNC_GPIO_1 (4) -#define TEST_SYNC_GPIO_2 (5) -#endif //CONFIG_IDF_TARGET_ESP32 - -// MCPWM default resolution -#if CONFIG_IDF_TARGET_ESP32H2 -#define MCPWM_TEST_GROUP_CLK_HZ (12 * 1000 * 1000) -#else -#define MCPWM_TEST_GROUP_CLK_HZ (10 * 1000 * 1000) -#endif - -#define MCPWM_TEST_TIMER_CLK_HZ (1 * 1000 * 1000) - -const static mcpwm_io_signals_t pwma[] = {MCPWM0A, MCPWM1A, MCPWM2A}; -const static mcpwm_io_signals_t pwmb[] = {MCPWM0B, MCPWM1B, MCPWM2B}; -const static mcpwm_fault_signal_t fault_sig_array[] = {MCPWM_SELECT_F0, MCPWM_SELECT_F1, MCPWM_SELECT_F2}; -const static mcpwm_io_signals_t fault_io_sig_array[] = {MCPWM_FAULT_0, MCPWM_FAULT_1, MCPWM_FAULT_2}; -const static mcpwm_sync_signal_t sync_sig_array[] = {MCPWM_SELECT_GPIO_SYNC0, MCPWM_SELECT_GPIO_SYNC1, MCPWM_SELECT_GPIO_SYNC2}; -const static mcpwm_io_signals_t sync_io_sig_array[] = {MCPWM_SYNC_0, MCPWM_SYNC_1, MCPWM_SYNC_2}; -const static mcpwm_capture_signal_t cap_sig_array[] = {MCPWM_SELECT_CAP0, MCPWM_SELECT_CAP1, MCPWM_SELECT_CAP2}; -const static mcpwm_io_signals_t cap_io_sig_array[] = {MCPWM_CAP_0, MCPWM_CAP_1, MCPWM_CAP_2}; - -#if SOC_PCNT_SUPPORTED -static pcnt_unit_handle_t pcnt_unit_a; -static pcnt_channel_handle_t pcnt_chan_a; -static pcnt_unit_handle_t pcnt_unit_b; -static pcnt_channel_handle_t pcnt_chan_b; -#endif - -// This GPIO init function is almost the same to public API `mcpwm_gpio_init()`, except that -// this function will configure all MCPWM GPIOs into output and input capable -// which is useful to simulate a trigger source -static esp_err_t test_mcpwm_gpio_init(mcpwm_unit_t mcpwm_num, mcpwm_io_signals_t io_signal, int gpio_num) -{ - if (gpio_num < 0) { // ignore on minus gpio number - return ESP_OK; - } - - if (io_signal <= MCPWM2B) { // Generator output signal - gpio_set_direction(gpio_num, GPIO_MODE_INPUT_OUTPUT); - int operator_id = io_signal / 2; - int generator_id = io_signal % 2; - esp_rom_gpio_connect_out_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].operators[operator_id].generators[generator_id].pwm_sig, 0, 0); - } else if (io_signal <= MCPWM_SYNC_2) { // External sync input signal - gpio_set_direction(gpio_num, GPIO_MODE_INPUT_OUTPUT); - int gpio_sync_id = io_signal - MCPWM_SYNC_0; - esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].gpio_synchros[gpio_sync_id].sync_sig, 0); - } else if (io_signal <= MCPWM_FAULT_2) { // Fault input signal - gpio_set_direction(gpio_num, GPIO_MODE_INPUT_OUTPUT); - int fault_id = io_signal - MCPWM_FAULT_0; - esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].gpio_faults[fault_id].fault_sig, 0); - } else if (io_signal >= MCPWM_CAP_0 && io_signal <= MCPWM_CAP_2) { // Capture input signal - gpio_set_direction(gpio_num, GPIO_MODE_INPUT_OUTPUT); - int capture_id = io_signal - MCPWM_CAP_0; - esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].captures[capture_id].cap_sig, 0); - } - gpio_func_sel(gpio_num, PIN_FUNC_GPIO); - return ESP_OK; -} - -static void mcpwm_setup_testbench(mcpwm_unit_t group, mcpwm_timer_t timer, uint32_t pwm_freq, float pwm_duty, - unsigned long int group_resolution, unsigned long int timer_resolution) -{ - mcpwm_io_signals_t mcpwm_a = pwma[timer]; - TEST_ESP_OK(test_mcpwm_gpio_init(group, mcpwm_a, TEST_PWMA_GPIO)); - - mcpwm_io_signals_t mcpwm_b = pwmb[timer]; - TEST_ESP_OK(test_mcpwm_gpio_init(group, mcpwm_b, TEST_PWMB_GPIO)); - - // Set PWM freq and duty, start immediately - mcpwm_config_t pwm_config = { - .frequency = pwm_freq, - .cmpr_a = pwm_duty, - .cmpr_b = pwm_duty, - .counter_mode = MCPWM_UP_COUNTER, - .duty_mode = MCPWM_DUTY_MODE_0, - }; - mcpwm_group_set_resolution(group, group_resolution); - mcpwm_timer_set_resolution(group, timer, timer_resolution); - TEST_ESP_OK(mcpwm_init(group, timer, &pwm_config)); -} - -#if SOC_PCNT_SUPPORTED -static void pcnt_setup_testbench(void) -{ - // PWMA <--> PCNT UNIT0 - pcnt_unit_config_t unit_a_config = { - .high_limit = 10000, - .low_limit = -10000, - }; - TEST_ESP_OK(pcnt_new_unit(&unit_a_config, &pcnt_unit_a)); - pcnt_chan_config_t chan_a_config = { - .edge_gpio_num = TEST_PWMA_GPIO, - .level_gpio_num = -1, // don't care level signal - }; - TEST_ESP_OK(pcnt_new_channel(pcnt_unit_a, &chan_a_config, &pcnt_chan_a)); - TEST_ESP_OK(pcnt_channel_set_edge_action(pcnt_chan_a, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_HOLD)); - TEST_ESP_OK(pcnt_channel_set_level_action(pcnt_chan_a, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_KEEP)); - TEST_ESP_OK(pcnt_unit_enable(pcnt_unit_a)); - - // PWMB <--> PCNT UNIT1 - pcnt_unit_config_t unit_b_config = { - .high_limit = 10000, - .low_limit = -10000, - }; - TEST_ESP_OK(pcnt_new_unit(&unit_b_config, &pcnt_unit_b)); - pcnt_chan_config_t chan_b_config = { - .edge_gpio_num = TEST_PWMB_GPIO, - .level_gpio_num = -1, // don't care level signal - }; - TEST_ESP_OK(pcnt_new_channel(pcnt_unit_b, &chan_b_config, &pcnt_chan_b)); - TEST_ESP_OK(pcnt_channel_set_edge_action(pcnt_chan_b, PCNT_CHANNEL_EDGE_ACTION_INCREASE, PCNT_CHANNEL_EDGE_ACTION_HOLD)); - TEST_ESP_OK(pcnt_channel_set_level_action(pcnt_chan_b, PCNT_CHANNEL_LEVEL_ACTION_KEEP, PCNT_CHANNEL_LEVEL_ACTION_KEEP)); - TEST_ESP_OK(pcnt_unit_enable(pcnt_unit_b)); -} - -static void pcnt_tear_testbench(void) -{ - TEST_ESP_OK(pcnt_unit_disable(pcnt_unit_a)); - TEST_ESP_OK(pcnt_unit_disable(pcnt_unit_b)); - TEST_ESP_OK(pcnt_del_channel(pcnt_chan_a)); - TEST_ESP_OK(pcnt_del_channel(pcnt_chan_b)); - TEST_ESP_OK(pcnt_del_unit(pcnt_unit_a)); - TEST_ESP_OK(pcnt_del_unit(pcnt_unit_b)); -} - -static uint32_t pcnt_get_pulse_number(pcnt_unit_handle_t pwm_pcnt_unit, int capture_window_ms) -{ - int count_value = 0; - TEST_ESP_OK(pcnt_unit_clear_count(pwm_pcnt_unit)); - TEST_ESP_OK(pcnt_unit_start(pwm_pcnt_unit)); - vTaskDelay(pdMS_TO_TICKS(capture_window_ms)); - TEST_ESP_OK(pcnt_unit_stop(pwm_pcnt_unit)); - TEST_ESP_OK(pcnt_unit_get_count(pwm_pcnt_unit, &count_value)); - printf("count value: %d\r\n", count_value); - return (uint32_t)count_value; -} -#endif // SOC_PCNT_SUPPORTED - -static void mcpwm_timer_duty_test(mcpwm_unit_t unit, mcpwm_timer_t timer, unsigned long int group_resolution, unsigned long int timer_resolution) -{ - mcpwm_setup_testbench(unit, timer, 1000, 50.0, group_resolution, timer_resolution); - vTaskDelay(pdMS_TO_TICKS(100)); - - TEST_ESP_OK(mcpwm_set_duty(unit, timer, MCPWM_OPR_A, 10.0)); - TEST_ESP_OK(mcpwm_set_duty(unit, timer, MCPWM_OPR_B, 20.0)); - TEST_ASSERT_FLOAT_WITHIN(0.1, 10.0, mcpwm_get_duty(unit, timer, MCPWM_OPR_A)); - TEST_ASSERT_FLOAT_WITHIN(0.1, 20.0, mcpwm_get_duty(unit, timer, MCPWM_OPR_B)); - vTaskDelay(pdMS_TO_TICKS(100)); - - TEST_ESP_OK(mcpwm_set_duty(unit, timer, MCPWM_OPR_A, 55.5f)); - TEST_ESP_OK(mcpwm_set_duty_type(unit, timer, MCPWM_OPR_A, MCPWM_DUTY_MODE_0)); - TEST_ASSERT_FLOAT_WITHIN(0.1, 55.5, mcpwm_get_duty(unit, timer, MCPWM_OPR_A)); - vTaskDelay(pdMS_TO_TICKS(100)); - - TEST_ESP_OK(mcpwm_set_duty_in_us(unit, timer, MCPWM_OPR_B, 500)); - TEST_ASSERT_INT_WITHIN(5, 500, mcpwm_get_duty_in_us(unit, timer, MCPWM_OPR_B)); - vTaskDelay(pdMS_TO_TICKS(100)); - - TEST_ESP_OK(mcpwm_stop(unit, timer)); - vTaskDelay(pdMS_TO_TICKS(100)); -} - -TEST_CASE("MCPWM duty test", "[mcpwm]") -{ - for (int i = 0; i < SOC_MCPWM_GROUPS; i++) { - for (int j = 0; j < SOC_MCPWM_TIMERS_PER_GROUP; j++) { - mcpwm_timer_duty_test(i, j, MCPWM_TEST_GROUP_CLK_HZ, MCPWM_TEST_TIMER_CLK_HZ); - mcpwm_timer_duty_test(i, j, MCPWM_TEST_GROUP_CLK_HZ / 2, MCPWM_TEST_TIMER_CLK_HZ * 2); - } - } -} - -// ------------------------------------------------------------------------------------- - -#if SOC_PCNT_SUPPORTED -static void mcpwm_start_stop_test(mcpwm_unit_t unit, mcpwm_timer_t timer) -{ - uint32_t pulse_number = 0; - - pcnt_setup_testbench(); - mcpwm_setup_testbench(unit, timer, 1000, 50.0, MCPWM_TEST_GROUP_CLK_HZ, MCPWM_TEST_TIMER_CLK_HZ); // Period: 1000us, 1ms - // count the pulse number within 100ms - pulse_number = pcnt_get_pulse_number(pcnt_unit_a, 100); - TEST_ASSERT_INT_WITHIN(2, 100, pulse_number); - pulse_number = pcnt_get_pulse_number(pcnt_unit_b, 100); - TEST_ASSERT_INT_WITHIN(2, 100, pulse_number); - - TEST_ESP_OK(mcpwm_set_frequency(unit, timer, 100)); - pulse_number = pcnt_get_pulse_number(pcnt_unit_b, 100); - TEST_ASSERT_INT_WITHIN(2, 10, pulse_number); - - // stop timer, then no pwm pulse should be generating - TEST_ESP_OK(mcpwm_stop(unit, timer)); - usleep(10000); // wait until timer stopped - pulse_number = pcnt_get_pulse_number(pcnt_unit_a, 100); - TEST_ASSERT_INT_WITHIN(2, 0, pulse_number); - pulse_number = pcnt_get_pulse_number(pcnt_unit_b, 100); - TEST_ASSERT_INT_WITHIN(2, 0, pulse_number); - pcnt_tear_testbench(); -} - -TEST_CASE("MCPWM start and stop test", "[mcpwm]") -{ - for (int i = 0; i < SOC_MCPWM_GROUPS; i++) { - for (int j = 0; j < SOC_MCPWM_TIMERS_PER_GROUP; j++) { - mcpwm_start_stop_test(i, j); - } - } -} -#endif // SOC_PCNT_SUPPORTED - -// ------------------------------------------------------------------------------------- - -static void mcpwm_deadtime_test(mcpwm_unit_t unit, mcpwm_timer_t timer) -{ - mcpwm_setup_testbench(unit, timer, 1000, 50.0, MCPWM_TEST_GROUP_CLK_HZ, MCPWM_TEST_TIMER_CLK_HZ); // Period: 1000us, 1ms - mcpwm_deadtime_type_t deadtime_type[] = {MCPWM_BYPASS_RED, MCPWM_BYPASS_FED, MCPWM_ACTIVE_HIGH_MODE, - MCPWM_ACTIVE_LOW_MODE, MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE, MCPWM_ACTIVE_LOW_COMPLIMENT_MODE, - MCPWM_ACTIVE_RED_FED_FROM_PWMXA, MCPWM_ACTIVE_RED_FED_FROM_PWMXB - }; - - for (size_t i = 0; i < sizeof(deadtime_type) / sizeof(deadtime_type[0]); i++) { - mcpwm_stop(unit, timer); - usleep(10000); - mcpwm_deadtime_enable(unit, timer, deadtime_type[i], 1000, 1000); - mcpwm_start(unit, timer); - vTaskDelay(pdMS_TO_TICKS(100)); - mcpwm_deadtime_disable(unit, timer); - } - mcpwm_stop(unit, timer); -} - -TEST_CASE("MCPWM deadtime test", "[mcpwm]") -{ - for (int i = 0; i < SOC_MCPWM_GROUPS; i++) { - for (int j = 0; j < SOC_MCPWM_TIMERS_PER_GROUP; j++) { - mcpwm_deadtime_test(i, j); - } - } -} - -// ------------------------------------------------------------------------------------- -#if SOC_PCNT_SUPPORTED -#define TEST_CARRIER_FREQ 250000 -static void mcpwm_carrier_test(mcpwm_unit_t unit, mcpwm_timer_t timer, mcpwm_carrier_out_ivt_t invert_or_not, - uint8_t period, uint8_t duty, uint8_t os_width) -{ - uint32_t pulse_number = 0; - - pcnt_setup_testbench(); - mcpwm_setup_testbench(unit, timer, 1000, 50.0, MCPWM_TEST_GROUP_CLK_HZ, MCPWM_TEST_TIMER_CLK_HZ); - mcpwm_set_signal_high(unit, timer, MCPWM_GEN_A); - mcpwm_set_signal_high(unit, timer, MCPWM_GEN_B); - TEST_ESP_OK(mcpwm_carrier_enable(unit, timer)); - TEST_ESP_OK(mcpwm_carrier_set_period(unit, timer, period)); //carrier revolution - TEST_ESP_OK(mcpwm_carrier_set_duty_cycle(unit, timer, duty)); // carrier duty - TEST_ESP_OK(mcpwm_carrier_output_invert(unit, timer, invert_or_not)); - TEST_ESP_OK(mcpwm_carrier_oneshot_mode_enable(unit, timer, os_width)); - vTaskDelay(pdMS_TO_TICKS(100)); - - pulse_number = pcnt_get_pulse_number(pcnt_unit_a, 10); - TEST_ASSERT_INT_WITHIN(50, (TEST_CARRIER_FREQ / 100), pulse_number); - usleep(10000); - pulse_number = pcnt_get_pulse_number(pcnt_unit_b, 10); - TEST_ASSERT_INT_WITHIN(50, (TEST_CARRIER_FREQ / 100), pulse_number); - - TEST_ESP_OK(mcpwm_carrier_disable(unit, timer)); - TEST_ESP_OK(mcpwm_stop(unit, timer)); - pcnt_tear_testbench(); -} - -TEST_CASE("MCPWM carrier test", "[mcpwm]") -{ - for (int i = 0; i < SOC_MCPWM_GROUPS; i++) { - for (int j = 0; j < SOC_MCPWM_TIMERS_PER_GROUP; j++) { - // carrier should be 10MHz/8/(4+1) = 250KHz, (10MHz is the group resolution, it's fixed in the driver), carrier duty cycle is 4/8 = 50% - // (MCPWM_TEST_GROUP_CLK_HZ/8/TEST_CARRIER_FREQ - 1) should be a integer - mcpwm_carrier_test(i, j, MCPWM_CARRIER_OUT_IVT_DIS, (MCPWM_TEST_GROUP_CLK_HZ / 8 / TEST_CARRIER_FREQ - 1), 4, 3); - mcpwm_carrier_test(i, j, MCPWM_CARRIER_OUT_IVT_EN, (MCPWM_TEST_GROUP_CLK_HZ / 8 / TEST_CARRIER_FREQ - 1), 4, 3); - } - } -} -#endif // SOC_PCNT_SUPPORTED - -// ------------------------------------------------------------------------------------- - -static void mcpwm_check_generator_level_on_fault(mcpwm_action_on_pwmxa_t action_a, mcpwm_action_on_pwmxb_t action_b) -{ - if (action_a == MCPWM_ACTION_FORCE_LOW) { - TEST_ASSERT_EQUAL(0, gpio_get_level(TEST_PWMA_GPIO)); - } else if (action_a == MCPWM_ACTION_FORCE_HIGH) { - TEST_ASSERT_EQUAL(1, gpio_get_level(TEST_PWMA_GPIO)); - } - - if (action_b == MCPWM_ACTION_FORCE_LOW) { - TEST_ASSERT_EQUAL(0, gpio_get_level(TEST_PWMB_GPIO)); - } else if (action_b == MCPWM_ACTION_FORCE_HIGH) { - TEST_ASSERT_EQUAL(1, gpio_get_level(TEST_PWMB_GPIO)); - } -} - -static void mcpwm_fault_cbc_test(mcpwm_unit_t unit, mcpwm_timer_t timer) -{ - mcpwm_action_on_pwmxa_t action_a[] = {MCPWM_ACTION_FORCE_LOW, MCPWM_ACTION_FORCE_HIGH}; - mcpwm_action_on_pwmxb_t action_b[] = {MCPWM_ACTION_FORCE_LOW, MCPWM_ACTION_FORCE_HIGH}; - - mcpwm_fault_signal_t fault_sig = fault_sig_array[timer]; - mcpwm_io_signals_t fault_io_sig = fault_io_sig_array[timer]; - - mcpwm_setup_testbench(unit, timer, 1000, 50.0, MCPWM_TEST_GROUP_CLK_HZ, MCPWM_TEST_TIMER_CLK_HZ); - TEST_ESP_OK(test_mcpwm_gpio_init(unit, fault_io_sig, TEST_FAULT_GPIO)); - gpio_set_level(TEST_FAULT_GPIO, 0); - TEST_ESP_OK(mcpwm_fault_init(unit, MCPWM_HIGH_LEVEL_TGR, fault_sig)); - for (int i = 0; i < sizeof(action_a) / sizeof(action_a[0]); i++) { - for (int j = 0; j < sizeof(action_b) / sizeof(action_b[0]); j++) { - TEST_ESP_OK(mcpwm_fault_set_cyc_mode(unit, timer, fault_sig, action_a[i], action_b[j])); - gpio_set_level(TEST_FAULT_GPIO, 1); // trigger the fault event - usleep(10000); - mcpwm_check_generator_level_on_fault(action_a[i], action_b[j]); - gpio_set_level(TEST_FAULT_GPIO, 0); // remove the fault signal - usleep(10000); - } - } - TEST_ESP_OK(mcpwm_fault_deinit(unit, fault_sig)); -} - -TEST_CASE("MCPWM fault cbc test", "[mcpwm]") -{ - for (int i = 0; i < SOC_MCPWM_GROUPS; i++) { - for (int j = 0; j < SOC_MCPWM_TIMERS_PER_GROUP; j++) { - mcpwm_fault_cbc_test(i, j); - } - } -} - -// ------------------------------------------------------------------------------------- - -static void mcpwm_fault_ost_test(mcpwm_unit_t unit, mcpwm_timer_t timer) -{ - mcpwm_action_on_pwmxa_t action_a[] = {MCPWM_ACTION_FORCE_LOW, MCPWM_ACTION_FORCE_HIGH}; - mcpwm_action_on_pwmxb_t action_b[] = {MCPWM_ACTION_FORCE_LOW, MCPWM_ACTION_FORCE_HIGH}; - - mcpwm_fault_signal_t fault_sig = fault_sig_array[timer]; - mcpwm_io_signals_t fault_io_sig = fault_io_sig_array[timer]; - - mcpwm_setup_testbench(unit, timer, 1000, 50.0, MCPWM_TEST_GROUP_CLK_HZ, MCPWM_TEST_TIMER_CLK_HZ); - TEST_ESP_OK(test_mcpwm_gpio_init(unit, fault_io_sig, TEST_FAULT_GPIO)); - gpio_set_level(TEST_FAULT_GPIO, 0); - TEST_ESP_OK(mcpwm_fault_init(unit, MCPWM_HIGH_LEVEL_TGR, fault_sig)); - for (int i = 0; i < sizeof(action_a) / sizeof(action_a[0]); i++) { - for (int j = 0; j < sizeof(action_b) / sizeof(action_b[0]); j++) { - TEST_ESP_OK(mcpwm_fault_set_oneshot_mode(unit, timer, fault_sig, action_a[i], action_b[j])); - gpio_set_level(TEST_FAULT_GPIO, 1); // trigger the fault event - usleep(10000); - mcpwm_check_generator_level_on_fault(action_a[i], action_b[j]); - gpio_set_level(TEST_FAULT_GPIO, 0); // remove the fault signal - usleep(10000); - } - } - TEST_ESP_OK(mcpwm_fault_deinit(unit, fault_sig)); -} - -TEST_CASE("MCPWM fault ost test", "[mcpwm]") -{ - for (int i = 0; i < SOC_MCPWM_GROUPS; i++) { - for (int j = 0; j < SOC_MCPWM_TIMERS_PER_GROUP; j++) { - mcpwm_fault_ost_test(i, j); - } - } -} - -// ------------------------------------------------------------------------------------- - -static void mcpwm_sync_test(mcpwm_unit_t unit, mcpwm_timer_t timer) -{ - mcpwm_sync_signal_t sync_sig = sync_sig_array[timer]; - mcpwm_io_signals_t sync_io_sig = sync_io_sig_array[timer]; - - mcpwm_setup_testbench(unit, timer, 1000, 50.0, MCPWM_TEST_GROUP_CLK_HZ, MCPWM_TEST_TIMER_CLK_HZ); - TEST_ESP_OK(test_mcpwm_gpio_init(unit, sync_io_sig, TEST_SYNC_GPIO_0)); - gpio_set_level(TEST_SYNC_GPIO_0, 0); - - mcpwm_sync_config_t sync_conf = { - .sync_sig = sync_sig, - .timer_val = 200, - .count_direction = MCPWM_TIMER_DIRECTION_UP, - }; - TEST_ESP_OK(mcpwm_sync_configure(unit, timer, &sync_conf)); - vTaskDelay(pdMS_TO_TICKS(50)); - gpio_set_level(TEST_SYNC_GPIO_0, 1); // trigger an external sync event - vTaskDelay(pdMS_TO_TICKS(50)); - mcpwm_timer_trigger_soft_sync(unit, timer); // trigger a software sync event - vTaskDelay(pdMS_TO_TICKS(50)); - TEST_ESP_OK(mcpwm_sync_disable(unit, timer)); - TEST_ESP_OK(mcpwm_stop(unit, timer)); -} - -TEST_CASE("MCPWM timer GPIO sync test", "[mcpwm]") -{ - for (int i = 0; i < SOC_MCPWM_GROUPS; i++) { - for (int j = 0; j < SOC_MCPWM_TIMERS_PER_GROUP; j++) { - mcpwm_sync_test(i, j); - } - } -} - -// used only in this area but need to be reset every time. mutex is not needed -// store timestamps captured from ISR callback -static uint64_t cap_timestamp[3]; -// control the start of capture to avoid unstable data -static volatile bool log_cap; - -// cb function, to update capture value -// only log when channel1 comes at first, then channel2, and do not log further more. -static bool test_mcpwm_capture_callback(mcpwm_unit_t mcpwm, mcpwm_capture_channel_id_t cap_channel, const cap_event_data_t *edata, - void *user_data) -{ - if (log_cap && (cap_timestamp[1] == 0 || cap_timestamp[2] == 0)) { - if (cap_channel == MCPWM_SELECT_CAP1 && cap_timestamp[1] == 0) { - cap_timestamp[1] = edata->cap_value; - } - if (cap_channel == MCPWM_SELECT_CAP2 && cap_timestamp[1] != 0) { - cap_timestamp[2] = edata->cap_value; - } - } - return false; -} - -static void mcpwm_swsync_test(mcpwm_unit_t unit) -{ - const uint32_t test_sync_phase = 20; - - cap_timestamp[0] = 0; - cap_timestamp[1] = 0; - cap_timestamp[2] = 0; - log_cap = false; - - // configure all timer output 10% PWM - for (int i = 0; i < 3; ++i) { - mcpwm_setup_testbench(unit, i, 1000, 10.0, MCPWM_TEST_GROUP_CLK_HZ, MCPWM_TEST_TIMER_CLK_HZ); - } - - vTaskDelay(pdMS_TO_TICKS(10)); - - // configure capture for verification - mcpwm_capture_config_t conf = { - .cap_edge = MCPWM_POS_EDGE, - .cap_prescale = 1, - .capture_cb = test_mcpwm_capture_callback, - .user_data = NULL, - }; - TEST_ESP_OK(test_mcpwm_gpio_init(unit, MCPWM_CAP_0, TEST_SYNC_GPIO_0)); - TEST_ESP_OK(test_mcpwm_gpio_init(unit, MCPWM_CAP_1, TEST_SYNC_GPIO_1)); - TEST_ESP_OK(test_mcpwm_gpio_init(unit, MCPWM_CAP_2, TEST_SYNC_GPIO_2)); - TEST_ESP_OK(mcpwm_capture_enable_channel(unit, MCPWM_SELECT_CAP0, &conf)); - TEST_ESP_OK(mcpwm_capture_enable_channel(unit, MCPWM_SELECT_CAP1, &conf)); - TEST_ESP_OK(mcpwm_capture_enable_channel(unit, MCPWM_SELECT_CAP2, &conf)); - // timer0 produce sync sig at TEZ, timer1 and timer2 consume, to make sure last two can be synced precisely - // timer1 and timer2 will be synced with TEZ of timer0 at a known phase. - mcpwm_sync_config_t sync_conf = { - .sync_sig = MCPWM_SELECT_TIMER0_SYNC, - .timer_val = 0, - .count_direction = MCPWM_TIMER_DIRECTION_UP, - }; - TEST_ESP_OK(mcpwm_sync_configure(unit, MCPWM_TIMER_1, &sync_conf)); - sync_conf.timer_val = 1000 - test_sync_phase; - TEST_ESP_OK(mcpwm_sync_configure(unit, MCPWM_TIMER_2, &sync_conf)); - TEST_ESP_OK(mcpwm_set_timer_sync_output(unit, MCPWM_TIMER_0, MCPWM_SWSYNC_SOURCE_TEZ)); - // init gpio at the end - TEST_ESP_OK(test_mcpwm_gpio_init(unit, MCPWM0A, TEST_SYNC_GPIO_0)); - TEST_ESP_OK(test_mcpwm_gpio_init(unit, MCPWM1A, TEST_SYNC_GPIO_1)); - TEST_ESP_OK(test_mcpwm_gpio_init(unit, MCPWM2A, TEST_SYNC_GPIO_2)); - - vTaskDelay(pdMS_TO_TICKS(100)); - - log_cap = true; - - vTaskDelay(pdMS_TO_TICKS(100)); - - uint32_t delta_timestamp_us = (cap_timestamp[2] - cap_timestamp[1]) * 1000000 / mcpwm_capture_get_resolution(unit); - uint32_t expected_phase_us = 1000000 / mcpwm_get_frequency(unit, MCPWM_TIMER_0) * test_sync_phase / 1000; - // accept +-2 error - TEST_ASSERT_UINT32_WITHIN(2, expected_phase_us, delta_timestamp_us); - - // tear down - for (int i = 0; i < 3; ++i) { - TEST_ESP_OK(mcpwm_capture_disable_channel(unit, i)); - TEST_ESP_OK(mcpwm_sync_disable(unit, i)); - TEST_ESP_OK(mcpwm_stop(unit, i)); - } -} - -TEST_CASE("MCPWM timer swsync test", "[mcpwm]") -{ - for (int i = 0; i < SOC_MCPWM_GROUPS; i++) { - mcpwm_swsync_test(i); - } -} - -// ------------------------------------------------------------------------------------- -typedef struct { - mcpwm_unit_t unit; - TaskHandle_t task_hdl; -} test_capture_callback_data_t; - -static bool test_mcpwm_intr_handler(mcpwm_unit_t mcpwm, mcpwm_capture_channel_id_t cap_sig, const cap_event_data_t *edata, void *arg) -{ - BaseType_t high_task_wakeup = pdFALSE; - test_capture_callback_data_t *cb_data = (test_capture_callback_data_t *)arg; - vTaskNotifyGiveFromISR(cb_data->task_hdl, &high_task_wakeup); - return high_task_wakeup == pdTRUE; -} - -static void mcpwm_capture_test(mcpwm_unit_t unit, mcpwm_capture_signal_t cap_chan) -{ - test_capture_callback_data_t callback_data = { - .unit = unit, - .task_hdl = xTaskGetCurrentTaskHandle(), - }; - - //each timer test the capture sig with the same id with it. - mcpwm_io_signals_t cap_io = cap_io_sig_array[cap_chan]; - mcpwm_capture_channel_id_t cap_channel = cap_sig_array[cap_chan]; - - TEST_ESP_OK(test_mcpwm_gpio_init(unit, cap_io, TEST_CAP_GPIO)); - mcpwm_capture_config_t conf = { - .cap_edge = MCPWM_POS_EDGE, - .cap_prescale = 1, - .capture_cb = test_mcpwm_intr_handler, - .user_data = &callback_data - }; - TEST_ESP_OK(mcpwm_capture_enable_channel(unit, cap_channel, &conf)); - // generate an posage - gpio_set_level(TEST_CAP_GPIO, 0); - gpio_set_level(TEST_CAP_GPIO, 1); - vTaskDelay(pdMS_TO_TICKS(100)); - TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(40))); - uint32_t cap_val0 = mcpwm_capture_signal_get_value(unit, cap_chan); - - // generate another posage - gpio_set_level(TEST_CAP_GPIO, 0); - gpio_set_level(TEST_CAP_GPIO, 1); - TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(40))); - uint32_t cap_val1 = mcpwm_capture_signal_get_value(unit, cap_chan); - uint32_t delta = mcpwm_capture_get_resolution(unit) / (cap_val1 - cap_val0); - TEST_ASSERT_UINT_WITHIN(2, 10, delta); - - TEST_ESP_OK(mcpwm_capture_disable_channel(unit, cap_channel)); -} - -TEST_CASE("MCPWM capture test", "[mcpwm]") -{ - // we assume each group has one capture timer - for (int i = 0; i < SOC_MCPWM_GROUPS; i++) { - for (int j = 0; j < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER; j++) { - mcpwm_capture_test(i, j); - } - } -} diff --git a/components/driver/test_apps/legacy_mcpwm_driver/pytest_legacy_mcpwm.py b/components/driver/test_apps/legacy_mcpwm_driver/pytest_legacy_mcpwm.py deleted file mode 100644 index b415ffed0a..0000000000 --- a/components/driver/test_apps/legacy_mcpwm_driver/pytest_legacy_mcpwm.py +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: CC0-1.0 -import pytest -from pytest_embedded import Dut -from pytest_embedded_idf.utils import idf_parametrize - - -@pytest.mark.generic -@pytest.mark.parametrize( - 'config', - [ - 'release', - ], - indirect=True, -) -@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) -def test_legacy_mcpwm(dut: Dut) -> None: - dut.run_all_single_board_cases() diff --git a/components/driver/test_apps/legacy_mcpwm_driver/sdkconfig.ci.release b/components/driver/test_apps/legacy_mcpwm_driver/sdkconfig.ci.release deleted file mode 100644 index 91d93f163e..0000000000 --- a/components/driver/test_apps/legacy_mcpwm_driver/sdkconfig.ci.release +++ /dev/null @@ -1,5 +0,0 @@ -CONFIG_PM_ENABLE=y -CONFIG_FREERTOS_USE_TICKLESS_IDLE=y -CONFIG_COMPILER_OPTIMIZATION_SIZE=y -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y -CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/driver/test_apps/legacy_mcpwm_driver/sdkconfig.defaults b/components/driver/test_apps/legacy_mcpwm_driver/sdkconfig.defaults deleted file mode 100644 index 9e494a19fb..0000000000 --- a/components/driver/test_apps/legacy_mcpwm_driver/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_FREERTOS_HZ=1000 -CONFIG_ESP_TASK_WDT_EN=n -CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN=y diff --git a/components/hal/esp32/include/hal/mcpwm_ll.h b/components/hal/esp32/include/hal/mcpwm_ll.h index d88a2253ea..bf92ff6b04 100644 --- a/components/hal/esp32/include/hal/mcpwm_ll.h +++ b/components/hal/esp32/include/hal/mcpwm_ll.h @@ -1622,48 +1622,6 @@ static inline void mcpwm_ll_capture_set_prescale(mcpwm_dev_t *mcpwm, int channel HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->cap_chn_cfg[channel], capn_prescale, prescale - 1); } -//////////////////////////////////////////Deprecated Functions////////////////////////////////////////////////////////// -/////////////////////////////The following functions are only used by the legacy driver///////////////////////////////// -/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static inline uint32_t mcpwm_ll_timer_get_peak(mcpwm_dev_t *mcpwm, int timer_id, bool symmetric) -{ - return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period) + (symmetric ? 0 : 1); -} - -static inline mcpwm_timer_count_mode_t mcpwm_ll_timer_get_count_mode(mcpwm_dev_t *mcpwm, int timer_id) -{ - switch (mcpwm->timer[timer_id].timer_cfg1.timer_mod) { - case 1: - return MCPWM_TIMER_COUNT_MODE_UP; - case 2: - return MCPWM_TIMER_COUNT_MODE_DOWN; - case 3: - return MCPWM_TIMER_COUNT_MODE_UP_DOWN; - case 0: - default: - return MCPWM_TIMER_COUNT_MODE_PAUSE; - } -} - -static inline uint32_t mcpwm_ll_operator_get_compare_value(mcpwm_dev_t *mcpwm, int operator_id, int compare_id) -{ - return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->operators[operator_id].timestamp[compare_id], gen); -} - -__attribute__((always_inline)) -static inline uint32_t mcpwm_ll_intr_get_capture_status(mcpwm_dev_t *mcpwm) -{ - return (mcpwm->int_st.val >> 27) & 0x07; -} - -__attribute__((always_inline)) -static inline void mcpwm_ll_intr_clear_capture_status(mcpwm_dev_t *mcpwm, uint32_t capture_mask) -{ - mcpwm->int_clr.val = (capture_mask & 0x07) << 27; -} - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c5/include/hal/mcpwm_ll.h b/components/hal/esp32c5/include/hal/mcpwm_ll.h index b1ba7b1362..bbf56a03c6 100644 --- a/components/hal/esp32c5/include/hal/mcpwm_ll.h +++ b/components/hal/esp32c5/include/hal/mcpwm_ll.h @@ -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 */ @@ -1683,48 +1683,6 @@ static inline void mcpwm_ll_etm_enable_evt_comparator_event(mcpwm_dev_t *mcpwm, } } -//////////////////////////////////////////Deprecated Functions////////////////////////////////////////////////////////// -/////////////////////////////The following functions are only used by the legacy driver///////////////////////////////// -/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static inline uint32_t mcpwm_ll_timer_get_peak(mcpwm_dev_t *mcpwm, int timer_id, bool symmetric) -{ - return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timern_period) + (symmetric ? 0 : 1); -} - -static inline mcpwm_timer_count_mode_t mcpwm_ll_timer_get_count_mode(mcpwm_dev_t *mcpwm, int timer_id) -{ - switch (mcpwm->timer[timer_id].timer_cfg1.timern_mod) { - case 1: - return MCPWM_TIMER_COUNT_MODE_UP; - case 2: - return MCPWM_TIMER_COUNT_MODE_DOWN; - case 3: - return MCPWM_TIMER_COUNT_MODE_UP_DOWN; - case 0: - default: - return MCPWM_TIMER_COUNT_MODE_PAUSE; - } -} - -static inline uint32_t mcpwm_ll_operator_get_compare_value(mcpwm_dev_t *mcpwm, int operator_id, int compare_id) -{ - return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->operators[operator_id].timestamp[compare_id], cmprn); -} - -__attribute__((always_inline)) -static inline uint32_t mcpwm_ll_intr_get_capture_status(mcpwm_dev_t *mcpwm) -{ - return (mcpwm->int_st.val >> 27) & 0x07; -} - -__attribute__((always_inline)) -static inline void mcpwm_ll_intr_clear_capture_status(mcpwm_dev_t *mcpwm, uint32_t capture_mask) -{ - mcpwm->int_clr.val = (capture_mask & 0x07) << 27; -} - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/include/hal/mcpwm_ll.h b/components/hal/esp32c6/include/hal/mcpwm_ll.h index c535e64116..c31dc3d189 100644 --- a/components/hal/esp32c6/include/hal/mcpwm_ll.h +++ b/components/hal/esp32c6/include/hal/mcpwm_ll.h @@ -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 */ @@ -1644,48 +1644,6 @@ static inline void mcpwm_ll_etm_enable_comparator_event(mcpwm_dev_t *mcpwm, int } } -//////////////////////////////////////////Deprecated Functions////////////////////////////////////////////////////////// -/////////////////////////////The following functions are only used by the legacy driver///////////////////////////////// -/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static inline uint32_t mcpwm_ll_timer_get_peak(mcpwm_dev_t *mcpwm, int timer_id, bool symmetric) -{ - return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period) + (symmetric ? 0 : 1); -} - -static inline mcpwm_timer_count_mode_t mcpwm_ll_timer_get_count_mode(mcpwm_dev_t *mcpwm, int timer_id) -{ - switch (mcpwm->timer[timer_id].timer_cfg1.timer_mod) { - case 1: - return MCPWM_TIMER_COUNT_MODE_UP; - case 2: - return MCPWM_TIMER_COUNT_MODE_DOWN; - case 3: - return MCPWM_TIMER_COUNT_MODE_UP_DOWN; - case 0: - default: - return MCPWM_TIMER_COUNT_MODE_PAUSE; - } -} - -static inline uint32_t mcpwm_ll_operator_get_compare_value(mcpwm_dev_t *mcpwm, int operator_id, int compare_id) -{ - return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->operators[operator_id].timestamp[compare_id], cmpr); -} - -__attribute__((always_inline)) -static inline uint32_t mcpwm_ll_intr_get_capture_status(mcpwm_dev_t *mcpwm) -{ - return (mcpwm->int_st.val >> 27) & 0x07; -} - -__attribute__((always_inline)) -static inline void mcpwm_ll_intr_clear_capture_status(mcpwm_dev_t *mcpwm, uint32_t capture_mask) -{ - mcpwm->int_clr.val = (capture_mask & 0x07) << 27; -} - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h2/include/hal/mcpwm_ll.h b/components/hal/esp32h2/include/hal/mcpwm_ll.h index b78b503a5e..1f7724dc65 100644 --- a/components/hal/esp32h2/include/hal/mcpwm_ll.h +++ b/components/hal/esp32h2/include/hal/mcpwm_ll.h @@ -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 */ @@ -1642,48 +1642,6 @@ static inline void mcpwm_ll_etm_enable_comparator_event(mcpwm_dev_t *mcpwm, int } } -//////////////////////////////////////////Deprecated Functions////////////////////////////////////////////////////////// -/////////////////////////////The following functions are only used by the legacy driver///////////////////////////////// -/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static inline uint32_t mcpwm_ll_timer_get_peak(mcpwm_dev_t *mcpwm, int timer_id, bool symmetric) -{ - return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period) + (symmetric ? 0 : 1); -} - -static inline mcpwm_timer_count_mode_t mcpwm_ll_timer_get_count_mode(mcpwm_dev_t *mcpwm, int timer_id) -{ - switch (mcpwm->timer[timer_id].timer_cfg1.timer_mod) { - case 1: - return MCPWM_TIMER_COUNT_MODE_UP; - case 2: - return MCPWM_TIMER_COUNT_MODE_DOWN; - case 3: - return MCPWM_TIMER_COUNT_MODE_UP_DOWN; - case 0: - default: - return MCPWM_TIMER_COUNT_MODE_PAUSE; - } -} - -static inline uint32_t mcpwm_ll_operator_get_compare_value(mcpwm_dev_t *mcpwm, int operator_id, int compare_id) -{ - return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->operators[operator_id].timestamp[compare_id], cmpr); -} - -__attribute__((always_inline)) -static inline uint32_t mcpwm_ll_intr_get_capture_status(mcpwm_dev_t *mcpwm) -{ - return (mcpwm->int_st.val >> 27) & 0x07; -} - -__attribute__((always_inline)) -static inline void mcpwm_ll_intr_clear_capture_status(mcpwm_dev_t *mcpwm, uint32_t capture_mask) -{ - mcpwm->int_clr.val = (capture_mask & 0x07) << 27; -} - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/include/hal/mcpwm_ll.h b/components/hal/esp32p4/include/hal/mcpwm_ll.h index db8f2dd94d..a9cec3dbdd 100644 --- a/components/hal/esp32p4/include/hal/mcpwm_ll.h +++ b/components/hal/esp32p4/include/hal/mcpwm_ll.h @@ -1748,48 +1748,6 @@ static inline void mcpwm_ll_etm_enable_evt_comparator_event(mcpwm_dev_t *mcpwm, } } -//////////////////////////////////////////Deprecated Functions////////////////////////////////////////////////////////// -/////////////////////////////The following functions are only used by the legacy driver///////////////////////////////// -/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static inline uint32_t mcpwm_ll_timer_get_peak(mcpwm_dev_t *mcpwm, int timer_id, bool symmetric) -{ - return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period) + (symmetric ? 0 : 1); -} - -static inline mcpwm_timer_count_mode_t mcpwm_ll_timer_get_count_mode(mcpwm_dev_t *mcpwm, int timer_id) -{ - switch (mcpwm->timer[timer_id].timer_cfg1.timer_mod) { - case 1: - return MCPWM_TIMER_COUNT_MODE_UP; - case 2: - return MCPWM_TIMER_COUNT_MODE_DOWN; - case 3: - return MCPWM_TIMER_COUNT_MODE_UP_DOWN; - case 0: - default: - return MCPWM_TIMER_COUNT_MODE_PAUSE; - } -} - -static inline uint32_t mcpwm_ll_operator_get_compare_value(mcpwm_dev_t *mcpwm, int operator_id, int compare_id) -{ - return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->operators[operator_id].timestamp[compare_id], cmpr); -} - -__attribute__((always_inline)) -static inline uint32_t mcpwm_ll_intr_get_capture_status(mcpwm_dev_t *mcpwm) -{ - return (mcpwm->int_st.val >> 27) & 0x07; -} - -__attribute__((always_inline)) -static inline void mcpwm_ll_intr_clear_capture_status(mcpwm_dev_t *mcpwm, uint32_t capture_mask) -{ - mcpwm->int_clr.val = (capture_mask & 0x07) << 27; -} - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s3/include/hal/mcpwm_ll.h b/components/hal/esp32s3/include/hal/mcpwm_ll.h index e99604b50e..6c5893c5ff 100644 --- a/components/hal/esp32s3/include/hal/mcpwm_ll.h +++ b/components/hal/esp32s3/include/hal/mcpwm_ll.h @@ -1630,48 +1630,6 @@ static inline void mcpwm_ll_capture_set_prescale(mcpwm_dev_t *mcpwm, int channel HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->cap_chn_cfg[channel], capn_prescale, prescale - 1); } -//////////////////////////////////////////Deprecated Functions////////////////////////////////////////////////////////// -/////////////////////////////The following functions are only used by the legacy driver///////////////////////////////// -/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static inline uint32_t mcpwm_ll_timer_get_peak(mcpwm_dev_t *mcpwm, int timer_id, bool symmetric) -{ - return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period) + (symmetric ? 0 : 1); -} - -static inline mcpwm_timer_count_mode_t mcpwm_ll_timer_get_count_mode(mcpwm_dev_t *mcpwm, int timer_id) -{ - switch (mcpwm->timer[timer_id].timer_cfg1.timer_mod) { - case 1: - return MCPWM_TIMER_COUNT_MODE_UP; - case 2: - return MCPWM_TIMER_COUNT_MODE_DOWN; - case 3: - return MCPWM_TIMER_COUNT_MODE_UP_DOWN; - case 0: - default: - return MCPWM_TIMER_COUNT_MODE_PAUSE; - } -} - -static inline uint32_t mcpwm_ll_operator_get_compare_value(mcpwm_dev_t *mcpwm, int operator_id, int compare_id) -{ - return HAL_FORCE_READ_U32_REG_FIELD(mcpwm->operators[operator_id].timestamp[compare_id], gen); -} - -__attribute__((always_inline)) -static inline uint32_t mcpwm_ll_intr_get_capture_status(mcpwm_dev_t *mcpwm) -{ - return (mcpwm->int_st.val >> 27) & 0x07; -} - -__attribute__((always_inline)) -static inline void mcpwm_ll_intr_clear_capture_status(mcpwm_dev_t *mcpwm, uint32_t capture_mask) -{ - mcpwm->int_clr.val = (capture_mask & 0x07) << 27; -} - #ifdef __cplusplus } #endif diff --git a/docs/en/migration-guides/release-5.x/5.0/peripherals.rst b/docs/en/migration-guides/release-5.x/5.0/peripherals.rst index 993c919f2f..a9f76d501f 100644 --- a/docs/en/migration-guides/release-5.x/5.0/peripherals.rst +++ b/docs/en/migration-guides/release-5.x/5.0/peripherals.rst @@ -391,14 +391,16 @@ LCD .. only:: SOC_MCPWM_SUPPORTED - MCPWM - ----- + .. _deprecate_mcpwm_legacy_driver: + + Legacy MCPWM Driver is Deprecated + --------------------------------- MCPWM driver was redesigned (see :doc:`MCPWM <../../../api-reference/peripherals/mcpwm>`), meanwhile, the legacy driver is deprecated. The new driver's aim is to make each MCPWM submodule independent to each other, and give the freedom of resource connection back to users. - Although it is recommended to use the new driver APIs, the legacy driver is still available in the previous include path ``driver/mcpwm.h``. However, using legacy driver triggers the build warning below by default. This warning can be suppressed by the Kconfig option :ref:`CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN`. + Although it is recommended to use the new driver APIs, the legacy driver is still available in the previous include path ``driver/mcpwm.h``. However, using legacy driver triggers the build warning below by default. This warning can be suppressed by the Kconfig option ``CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN``. .. code-block:: text diff --git a/docs/en/migration-guides/release-6.x/6.0/peripherals.rst b/docs/en/migration-guides/release-6.x/6.0/peripherals.rst index 64499a6551..3b41d19f01 100644 --- a/docs/en/migration-guides/release-6.x/6.0/peripherals.rst +++ b/docs/en/migration-guides/release-6.x/6.0/peripherals.rst @@ -22,19 +22,28 @@ RMT The ``io_od_mode`` member in the :cpp:type:`rmt_tx_channel_config_t` configuration structure has been removed. If you want to use open-drain mode, you need to manually call the :func:`gpio_od_enable` function. -MCPWM ------ +.. only:: SOC_MCPWM_SUPPORTED -The ``io_od_mode`` member in the :cpp:type:`mcpwm_generator_config_t` configuration structure has been removed. If you want to use open-drain mode, you need to manually call the :func:`gpio_od_enable` function. + MCPWM + ----- -The ``pull_up`` and ``pull_down`` members have been removed from the following configuration structures. You need to manually call the :func:`gpio_set_pull_mode` function to configure the pull-up and pull-down resistors for the IO: + The ``io_od_mode`` member in the :cpp:type:`mcpwm_generator_config_t` configuration structure has been removed. If you want to use open-drain mode, you need to manually call the :func:`gpio_od_enable` function. -.. list:: + The ``pull_up`` and ``pull_down`` members have been removed from the following configuration structures. You need to manually call the :func:`gpio_set_pull_mode` function to configure the pull-up and pull-down resistors for the IO: - - :cpp:type:`mcpwm_generator_config_t` - - :cpp:type:`mcpwm_gpio_fault_config_t` - - :cpp:type:`mcpwm_gpio_sync_src_config_t` - - :cpp:type:`mcpwm_capture_channel_config_t` + .. list:: + + - :cpp:type:`mcpwm_generator_config_t` + - :cpp:type:`mcpwm_gpio_fault_config_t` + - :cpp:type:`mcpwm_gpio_sync_src_config_t` + - :cpp:type:`mcpwm_capture_channel_config_t` + + The default MCPWM group clock divider has been changed to 1. This allows you to obtain a higher default resolution. + + Legacy MCPWM Driver is Removed + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The legacy MCPWM driver ``driver/mcpwm.h`` is deprecated since version 5.0 (see :ref:`deprecate_mcpwm_legacy_driver`). Starting from version 6.0, the legacy driver is completely removed. The new driver is placed in the :component:`esp_driver_mcpwm`, and the header file path is ``driver/mcpwm_prelude``. GPIO ---- diff --git a/docs/zh_CN/migration-guides/release-5.x/5.0/peripherals.rst b/docs/zh_CN/migration-guides/release-5.x/5.0/peripherals.rst index 161a1c1bba..49750f0f42 100644 --- a/docs/zh_CN/migration-guides/release-5.x/5.0/peripherals.rst +++ b/docs/zh_CN/migration-guides/release-5.x/5.0/peripherals.rst @@ -390,14 +390,16 @@ LCD .. only:: SOC_MCPWM_SUPPORTED - MCPWM - ----- + .. _deprecate_mcpwm_legacy_driver: + + 旧版 MCPWM 驱动已弃用 + ----------------------------------- MCPWM 驱动已更新(详见 :doc:`MCPWM <../../../api-reference/peripherals/mcpwm>`)。同时,旧版驱动已被弃用。 新驱动中,每个 MCPWM 子模块相互独立,用户可以自由进行资源连接。 - 尽管我们推荐使用新的驱动 API,旧版驱动仍然可用,其引用路径为 ``driver/mcpwm.h``。但是,使用旧版驱动会默认触发如下编译警告,可以通过配置 Kconfig 选项 :ref:`CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN` 来关闭该警告。 + 尽管我们推荐使用新的驱动 API,旧版驱动仍然可用,其引用路径为 ``driver/mcpwm.h``。但是,使用旧版驱动会默认触发如下编译警告,可以通过配置 Kconfig 选项 ``CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN`` 来关闭该警告。 .. code-block:: text diff --git a/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst b/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst index e22e115c66..94960f5520 100644 --- a/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst +++ b/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst @@ -21,19 +21,28 @@ RMT :cpp:type:`rmt_tx_channel_config_t` 配置结构体中的 ``io_od_mode`` 已经被移除。如果想要使用开漏模式,你需要手动调用 GPIO 驱动中的 :func:`gpio_od_enable` 函数。 -MCPWM ------ +.. only:: SOC_MCPWM_SUPPORTED -:cpp:type:`mcpwm_generator_config_t` 配置结构体中的 ``io_od_mode`` 已经被移除。如果想要使用开漏模式,你需要手动调用 GPIO 驱动中的 :func:`gpio_od_enable` 函数。 + MCPWM + ----- -以下配置结构体中的 ``pull_up`` 和 ``pull_down`` 成员已经被移除,你需要手动调用 GPIO 驱动中的 :func:`gpio_set_pull_mode` 函数来配置 IO 上拉和下拉电阻: + :cpp:type:`mcpwm_generator_config_t` 配置结构体中的 ``io_od_mode`` 已经被移除。如果想要使用开漏模式,你需要手动调用 GPIO 驱动中的 :func:`gpio_od_enable` 函数。 -.. list:: + 以下配置结构体中的 ``pull_up`` 和 ``pull_down`` 成员已经被移除,你需要手动调用 GPIO 驱动中的 :func:`gpio_set_pull_mode` 函数来配置 IO 上拉和下拉电阻: - - :cpp:type:`mcpwm_generator_config_t` - - :cpp:type:`mcpwm_gpio_fault_config_t` - - :cpp:type:`mcpwm_gpio_sync_src_config_t` - - :cpp:type:`mcpwm_capture_channel_config_t` + .. list:: + + - :cpp:type:`mcpwm_generator_config_t` + - :cpp:type:`mcpwm_gpio_fault_config_t` + - :cpp:type:`mcpwm_gpio_sync_src_config_t` + - :cpp:type:`mcpwm_capture_channel_config_t` + + 默认的 MCPWM 群组时钟分频器已改为 1。这样,你就可以获得比以前更高的默认分辨率。 + + 旧版 MCPWM 驱动被移除 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + 旧版的 MCPWM 驱动 ``driver/mcpwm.h`` 在 5.0 的版本中就已经被弃用(请参考 :ref:`deprecate_mcpwm_legacy_driver`)。从 6.0 版本开始,旧版驱动被完全移除。新驱动位于 :component:`esp_driver_mcpwm` 组件中,头文件引用路径为 ``driver/mcpwm_prelude``。 GPIO ---- diff --git a/tools/idf_py_actions/hints.yml b/tools/idf_py_actions/hints.yml index be1b2ddf7b..2d35770d32 100644 --- a/tools/idf_py_actions/hints.yml +++ b/tools/idf_py_actions/hints.yml @@ -512,3 +512,6 @@ - re_variables: ['driver/adc.h'] hint_variables: ['legacy ADC', 'esp_adc/adc_oneshot.h, esp_adc/adc_continuous.h, esp_adc/adc_cali.h, esp_adc/adc_cali_scheme.h', 'esp_adc'] + - + re_variables: ['driver/mcpwm.h'] + hint_variables: ['legacy MCPWM', 'driver/mcpwm_prelude', 'esp_driver_mcpwm']