/* * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include #include #include #include "esp_err.h" #include "driver/mcpwm_types.h" #ifdef __cplusplus extern "C" { #endif /** * @brief MCPWM generator configuration */ typedef struct { int gen_gpio_num; /*!< The GPIO number used to output the PWM signal */ struct { uint32_t invert_pwm: 1; /*!< Whether to invert the PWM signal (done by GPIO matrix) */ uint32_t io_loop_back: 1; /*!< For debug/test, the signal output from the GPIO will be fed to the input path as well */ uint32_t io_od_mode: 1; /*!< Configure the GPIO as open-drain mode */ uint32_t pull_up: 1; /*!< Whether to pull up internally */ uint32_t pull_down: 1; /*!< Whether to pull down internally */ } flags; /*!< Extra configuration flags for generator */ } mcpwm_generator_config_t; /** * @brief Allocate MCPWM generator from given operator * * @param[in] oper MCPWM operator, allocated by `mcpwm_new_operator()` * @param[in] config MCPWM generator configuration * @param[out] ret_gen Returned MCPWM generator * @return * - ESP_OK: Create MCPWM generator successfully * - ESP_ERR_INVALID_ARG: Create MCPWM generator failed because of invalid argument * - ESP_ERR_NO_MEM: Create MCPWM generator failed because out of memory * - ESP_ERR_NOT_FOUND: Create MCPWM generator failed because can't find free resource * - ESP_FAIL: Create MCPWM generator failed because of other error */ esp_err_t mcpwm_new_generator(mcpwm_oper_handle_t oper, const mcpwm_generator_config_t *config, mcpwm_gen_handle_t *ret_gen); /** * @brief Delete MCPWM generator * * @param[in] gen MCPWM generator handle, allocated by `mcpwm_new_generator()` * @return * - ESP_OK: Delete MCPWM generator successfully * - ESP_ERR_INVALID_ARG: Delete MCPWM generator failed because of invalid argument * - ESP_FAIL: Delete MCPWM generator failed because of other error */ esp_err_t mcpwm_del_generator(mcpwm_gen_handle_t gen); /** * @brief Set force level for MCPWM generator * * @note The force level will be applied to the generator immediately, regardless any other events that would change the generator's behaviour. * @note If the `hold_on` is true, the force level will retain forever, until user removes the force level by setting the force level to `-1`. * @note If the `hold_on` is false, the force level can be overridden by the next event action. * @note The force level set by this function can be inverted by GPIO matrix or dead-time module. So the level set here doesn't equal to the final output level. * * @param[in] gen MCPWM generator handle, allocated by `mcpwm_new_generator()` * @param[in] level GPIO level to be applied to MCPWM generator, specially, -1 means to remove the force level * @param[in] hold_on Whether the forced PWM level should retain (i.e. will remain unchanged until manually remove the force level) * @return * - ESP_OK: Set force level for MCPWM generator successfully * - ESP_ERR_INVALID_ARG: Set force level for MCPWM generator failed because of invalid argument * - ESP_FAIL: Set force level for MCPWM generator failed because of other error */ esp_err_t mcpwm_generator_set_force_level(mcpwm_gen_handle_t gen, int level, bool hold_on); /** * @brief Generator action on specific timer event */ typedef struct { mcpwm_timer_direction_t direction; /*!< Timer direction */ mcpwm_timer_event_t event; /*!< Timer event */ mcpwm_generator_action_t action; /*!< Generator action should perform */ } mcpwm_gen_timer_event_action_t; /** * @brief Help macros to construct a mcpwm_gen_timer_event_action_t entry */ #define MCPWM_GEN_TIMER_EVENT_ACTION(dir, ev, act) \ (mcpwm_gen_timer_event_action_t) { .direction = dir, .event = ev, .action = act } #define MCPWM_GEN_TIMER_EVENT_ACTION_END() \ (mcpwm_gen_timer_event_action_t) { .event = MCPWM_TIMER_EVENT_INVALID } /** * @brief Set generator action on MCPWM timer event * * @param[in] gen MCPWM generator handle, allocated by `mcpwm_new_generator()` * @param[in] ev_act MCPWM timer event action, can be constructed by `MCPWM_GEN_TIMER_EVENT_ACTION` helper macro * @return * - ESP_OK: Set generator action successfully * - ESP_ERR_INVALID_ARG: Set generator action failed because of invalid argument * - ESP_ERR_INVALID_STATE: Set generator action failed because of timer is not connected to operator * - ESP_FAIL: Set generator action failed because of other error */ esp_err_t mcpwm_generator_set_action_on_timer_event(mcpwm_gen_handle_t gen, mcpwm_gen_timer_event_action_t ev_act); /** * @brief Set generator actions on multiple MCPWM timer events * * @note This is an aggregation version of `mcpwm_generator_set_action_on_timer_event`, which allows user to set multiple actions in one call. * * @param[in] gen MCPWM generator handle, allocated by `mcpwm_new_generator()` * @param[in] ev_act MCPWM timer event action list, must be terminated by `MCPWM_GEN_TIMER_EVENT_ACTION_END()` * @return * - ESP_OK: Set generator actions successfully * - ESP_ERR_INVALID_ARG: Set generator actions failed because of invalid argument * - ESP_ERR_INVALID_STATE: Set generator actions failed because of timer is not connected to operator * - ESP_FAIL: Set generator actions failed because of other error */ esp_err_t mcpwm_generator_set_actions_on_timer_event(mcpwm_gen_handle_t gen, mcpwm_gen_timer_event_action_t ev_act, ...); /** * @brief Generator action on specific comparator event */ typedef struct { mcpwm_timer_direction_t direction; /*!< Timer direction */ mcpwm_cmpr_handle_t comparator; /*!< Comparator handle */ mcpwm_generator_action_t action; /*!< Generator action should perform */ } mcpwm_gen_compare_event_action_t; /** * @brief Help macros to construct a mcpwm_gen_compare_event_action_t entry */ #define MCPWM_GEN_COMPARE_EVENT_ACTION(dir, cmp, act) \ (mcpwm_gen_compare_event_action_t) { .direction = dir, .comparator = cmp, .action = act } #define MCPWM_GEN_COMPARE_EVENT_ACTION_END() \ (mcpwm_gen_compare_event_action_t) { .comparator = NULL } /** * @brief Set generator action on MCPWM compare event * * @param[in] generator MCPWM generator handle, allocated by `mcpwm_new_generator()` * @param[in] ev_act MCPWM compare event action, can be constructed by `MCPWM_GEN_COMPARE_EVENT_ACTION` helper macro * @return * - ESP_OK: Set generator action successfully * - ESP_ERR_INVALID_ARG: Set generator action failed because of invalid argument * - ESP_FAIL: Set generator action failed because of other error */ esp_err_t mcpwm_generator_set_action_on_compare_event(mcpwm_gen_handle_t generator, mcpwm_gen_compare_event_action_t ev_act); /** * @brief Set generator actions on multiple MCPWM compare events * * @note This is an aggregation version of `mcpwm_generator_set_action_on_compare_event`, which allows user to set multiple actions in one call. * * @param[in] generator MCPWM generator handle, allocated by `mcpwm_new_generator()` * @param[in] ev_act MCPWM compare event action list, must be terminated by `MCPWM_GEN_COMPARE_EVENT_ACTION_END()` * @return * - ESP_OK: Set generator actions successfully * - ESP_ERR_INVALID_ARG: Set generator actions failed because of invalid argument * - ESP_FAIL: Set generator actions failed because of other error */ esp_err_t mcpwm_generator_set_actions_on_compare_event(mcpwm_gen_handle_t generator, mcpwm_gen_compare_event_action_t ev_act, ...); /** * @brief Generator action on specific brake event */ typedef struct { mcpwm_timer_direction_t direction; /*!< Timer direction */ mcpwm_operator_brake_mode_t brake_mode; /*!< Brake mode */ mcpwm_generator_action_t action; /*!< Generator action should perform */ } mcpwm_gen_brake_event_action_t; /** * @brief Help macros to construct a mcpwm_gen_brake_event_action_t entry */ #define MCPWM_GEN_BRAKE_EVENT_ACTION(dir, mode, act) \ (mcpwm_gen_brake_event_action_t) { .direction = dir, .brake_mode = mode, .action = act } #define MCPWM_GEN_BRAKE_EVENT_ACTION_END() \ (mcpwm_gen_brake_event_action_t) { .brake_mode = MCPWM_OPER_BRAKE_MODE_INVALID } /** * @brief Set generator action on MCPWM brake event * * @param[in] generator MCPWM generator handle, allocated by `mcpwm_new_generator()` * @param[in] ev_act MCPWM brake event action, can be constructed by `MCPWM_GEN_BRAKE_EVENT_ACTION` helper macro * @return * - ESP_OK: Set generator action successfully * - ESP_ERR_INVALID_ARG: Set generator action failed because of invalid argument * - ESP_FAIL: Set generator action failed because of other error */ esp_err_t mcpwm_generator_set_action_on_brake_event(mcpwm_gen_handle_t generator, mcpwm_gen_brake_event_action_t ev_act); /** * @brief Set generator actions on multiple MCPWM brake events * * @note This is an aggregation version of `mcpwm_generator_set_action_on_brake_event`, which allows user to set multiple actions in one call. * * @param[in] generator MCPWM generator handle, allocated by `mcpwm_new_generator()` * @param[in] ev_act MCPWM brake event action list, must be terminated by `MCPWM_GEN_BRAKE_EVENT_ACTION_END()` * @return * - ESP_OK: Set generator actions successfully * - ESP_ERR_INVALID_ARG: Set generator actions failed because of invalid argument * - ESP_FAIL: Set generator actions failed because of other error */ esp_err_t mcpwm_generator_set_actions_on_brake_event(mcpwm_gen_handle_t generator, mcpwm_gen_brake_event_action_t ev_act, ...); /** * @brief Generator action on specific fault event */ typedef struct { mcpwm_timer_direction_t direction; /*!< Timer direction */ mcpwm_fault_handle_t fault; /*!< Which fault as the trigger. Only support GPIO fault */ mcpwm_generator_action_t action; /*!< Generator action should perform */ } mcpwm_gen_fault_event_action_t; /** * @brief Help macros to construct a mcpwm_gen_fault_event_action_t entry */ #define MCPWM_GEN_FAULT_EVENT_ACTION(dir, flt, act) \ (mcpwm_gen_fault_event_action_t) { .direction = dir, .fault = flt, .action = act } /** * @brief Set generator action on MCPWM Fault event * * @param[in] generator MCPWM generator handle, allocated by `mcpwm_new_generator()` * @param[in] ev_act MCPWM trigger event action, can be constructed by `MCPWM_GEN_FAULT_EVENT_ACTION` helper macro * @return * - ESP_OK: Set generator action successfully * - ESP_ERR_INVALID_ARG: Set generator action failed because of invalid argument * - ESP_FAIL: Set generator action failed because of other error */ esp_err_t mcpwm_generator_set_action_on_fault_event(mcpwm_gen_handle_t generator, mcpwm_gen_fault_event_action_t ev_act); /** * @brief Generator action on specific sync event */ typedef struct { mcpwm_timer_direction_t direction; /*!< Timer direction */ mcpwm_sync_handle_t sync; /*!< Which sync as the trigger*/ mcpwm_generator_action_t action; /*!< Generator action should perform */ } mcpwm_gen_sync_event_action_t; /** * @brief Help macros to construct a mcpwm_gen_sync_event_action_t entry */ #define MCPWM_GEN_SYNC_EVENT_ACTION(dir, syn, act) \ (mcpwm_gen_sync_event_action_t) { .direction = dir, .sync = syn, .action = act } /** * @brief Set generator action on MCPWM Sync event * * @note The trigger only support one sync action, regardless of the kinds. Should not call this function more than once. * * @param[in] generator MCPWM generator handle, allocated by `mcpwm_new_generator()` * @param[in] ev_act MCPWM trigger event action, can be constructed by `MCPWM_GEN_SYNC_EVENT_ACTION` helper macro * @return * - ESP_OK: Set generator action successfully * - ESP_ERR_INVALID_ARG: Set generator action failed because of invalid argument * - ESP_FAIL: Set generator action failed because of other error */ esp_err_t mcpwm_generator_set_action_on_sync_event(mcpwm_gen_handle_t generator, mcpwm_gen_sync_event_action_t ev_act); /** * @brief MCPWM dead time configuration structure */ typedef struct { uint32_t posedge_delay_ticks; /*!< delay time applied to rising edge, 0 means no rising delay time */ uint32_t negedge_delay_ticks; /*!< delay time applied to falling edge, 0 means no falling delay time */ struct { uint32_t invert_output: 1; /*!< Invert the signal after applied the dead time */ } flags; /*!< Extra flags for dead time configuration */ } mcpwm_dead_time_config_t; /** * @brief Set dead time for MCPWM generator * * @note Due to a hardware limitation, you can't set rising edge delay for both MCPWM generator 0 and 1 at the same time, * otherwise, there will be a conflict inside the dead time module. The same goes for the falling edge setting. * But you can set both the rising edge and falling edge delay for the same MCPWM generator. * * @param[in] in_generator MCPWM generator, before adding the dead time * @param[in] out_generator MCPWM generator, after adding the dead time * @param[in] config MCPWM dead time configuration * @return * - ESP_OK: Set dead time for MCPWM generator successfully * - ESP_ERR_INVALID_ARG: Set dead time for MCPWM generator failed because of invalid argument * - ESP_ERR_INVALID_STATE: Set dead time for MCPWM generator failed because of invalid state (e.g. delay module is already in use by other generator) * - ESP_FAIL: Set dead time for MCPWM generator failed because of other error */ esp_err_t mcpwm_generator_set_dead_time(mcpwm_gen_handle_t in_generator, mcpwm_gen_handle_t out_generator, const mcpwm_dead_time_config_t *config); #ifdef __cplusplus } #endif