esp-idf/components/esp_driver_mcpwm/include/driver/mcpwm_gen.h

296 lines
14 KiB
C

/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#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