mcpwm: update hal and soc naming

This commit is contained in:
morris 2021-07-06 00:12:25 +08:00 committed by suda-morris
parent 47c4e5d63e
commit 88c87bfe56
12 changed files with 388 additions and 277 deletions

View File

@ -11,7 +11,6 @@
#include "esp_err.h" #include "esp_err.h"
#include "soc/soc.h" #include "soc/soc.h"
#include "driver/gpio.h" #include "driver/gpio.h"
#include "driver/periph_ctrl.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "hal/mcpwm_types.h" #include "hal/mcpwm_types.h"
@ -46,8 +45,7 @@ typedef enum {
} mcpwm_io_signals_t; } mcpwm_io_signals_t;
/** /**
* @brief MCPWM pin number for * @brief pin number for MCPWM
*
*/ */
typedef struct { typedef struct {
int mcpwm0a_out_num; /*!<MCPWM0A out pin*/ int mcpwm0a_out_num; /*!<MCPWM0A out pin*/
@ -71,9 +69,9 @@ typedef struct {
* @brief Select MCPWM unit * @brief Select MCPWM unit
*/ */
typedef enum { typedef enum {
MCPWM_UNIT_0 = 0, /*!<MCPWM unit0 selected*/ MCPWM_UNIT_0, /*!<MCPWM unit0 selected*/
MCPWM_UNIT_1, /*!<MCPWM unit1 selected*/ MCPWM_UNIT_1, /*!<MCPWM unit1 selected*/
MCPWM_UNIT_MAX, /*!<Num of MCPWM units on ESP32*/ MCPWM_UNIT_MAX, /*!<Max number of MCPWM units*/
} mcpwm_unit_t; } mcpwm_unit_t;
_Static_assert(MCPWM_UNIT_MAX == SOC_MCPWM_GROUPS, "MCPWM unit number not equal to chip capabilities"); _Static_assert(MCPWM_UNIT_MAX == SOC_MCPWM_GROUPS, "MCPWM unit number not equal to chip capabilities");
@ -82,17 +80,17 @@ _Static_assert(MCPWM_UNIT_MAX == SOC_MCPWM_GROUPS, "MCPWM unit number not equal
* @brief Select MCPWM timer * @brief Select MCPWM timer
*/ */
typedef enum { typedef enum {
MCPWM_TIMER_0 = 0, /*!<Select MCPWM timer0*/ MCPWM_TIMER_0, /*!<Select MCPWM timer0*/
MCPWM_TIMER_1, /*!<Select MCPWM timer1*/ MCPWM_TIMER_1, /*!<Select MCPWM timer1*/
MCPWM_TIMER_2, /*!<Select MCPWM timer2*/ MCPWM_TIMER_2, /*!<Select MCPWM timer2*/
MCPWM_TIMER_MAX, /*!<Num of MCPWM timers on ESP32*/ MCPWM_TIMER_MAX, /*!<Max number of timers in a unit*/
} mcpwm_timer_t; } mcpwm_timer_t;
/** /**
* @brief Select MCPWM operator * @brief Select MCPWM operator
*/ */
typedef enum { typedef enum {
MCPWM_GEN_A = 0, /*!<Select MCPWMXA, where 'X' is operator number*/ MCPWM_GEN_A, /*!<Select MCPWMXA, where 'X' is operator number*/
MCPWM_GEN_B, /*!<Select MCPWMXB, where 'X' is operator number*/ MCPWM_GEN_B, /*!<Select MCPWMXB, where 'X' is operator number*/
MCPWM_GEN_MAX, /*!<Num of generators to each operator of MCPWM*/ MCPWM_GEN_MAX, /*!<Num of generators to each operator of MCPWM*/
} mcpwm_generator_t; } mcpwm_generator_t;
@ -107,7 +105,7 @@ typedef mcpwm_generator_t mcpwm_operator_t; ///< @deprecated
* @brief MCPWM carrier oneshot mode, in this mode the width of the first pulse of carrier can be programmed * @brief MCPWM carrier oneshot mode, in this mode the width of the first pulse of carrier can be programmed
*/ */
typedef enum { typedef enum {
MCPWM_ONESHOT_MODE_DIS = 0, /*!<Enable oneshot mode*/ MCPWM_ONESHOT_MODE_DIS, /*!<Enable oneshot mode*/
MCPWM_ONESHOT_MODE_EN, /*!<Disable oneshot mode*/ MCPWM_ONESHOT_MODE_EN, /*!<Disable oneshot mode*/
} mcpwm_carrier_os_t; } mcpwm_carrier_os_t;
@ -115,7 +113,7 @@ typedef enum {
* @brief MCPWM carrier output inversion, high frequency carrier signal active with MCPWM signal is high * @brief MCPWM carrier output inversion, high frequency carrier signal active with MCPWM signal is high
*/ */
typedef enum { typedef enum {
MCPWM_CARRIER_OUT_IVT_DIS = 0, /*!<Enable carrier output inversion*/ MCPWM_CARRIER_OUT_IVT_DIS, /*!<Enable carrier output inversion*/
MCPWM_CARRIER_OUT_IVT_EN, /*!<Disable carrier output inversion*/ MCPWM_CARRIER_OUT_IVT_EN, /*!<Disable carrier output inversion*/
} mcpwm_carrier_out_ivt_t; } mcpwm_carrier_out_ivt_t;
@ -123,7 +121,7 @@ typedef enum {
* @brief MCPWM select fault signal input * @brief MCPWM select fault signal input
*/ */
typedef enum { typedef enum {
MCPWM_SELECT_F0 = 0, /*!<Select F0 as input*/ MCPWM_SELECT_F0, /*!<Select F0 as input*/
MCPWM_SELECT_F1, /*!<Select F1 as input*/ MCPWM_SELECT_F1, /*!<Select F1 as input*/
MCPWM_SELECT_F2, /*!<Select F2 as input*/ MCPWM_SELECT_F2, /*!<Select F2 as input*/
} mcpwm_fault_signal_t; } mcpwm_fault_signal_t;
@ -141,7 +139,7 @@ typedef enum {
* @brief MCPWM select triggering level of fault signal * @brief MCPWM select triggering level of fault signal
*/ */
typedef enum { typedef enum {
MCPWM_LOW_LEVEL_TGR = 0, /*!<Fault condition occurs when fault input signal goes from high to low, currently not supported*/ MCPWM_LOW_LEVEL_TGR, /*!<Fault condition occurs when fault input signal goes from high to low, currently not supported*/
MCPWM_HIGH_LEVEL_TGR, /*!<Fault condition occurs when fault input signal goes low to high*/ MCPWM_HIGH_LEVEL_TGR, /*!<Fault condition occurs when fault input signal goes low to high*/
} mcpwm_fault_input_level_t; } mcpwm_fault_input_level_t;
@ -189,7 +187,7 @@ typedef enum {
MCPWM_ACTIVE_LOW_COMPLIMENT_MODE, /*!<MCPWMXA = compliment of rising edge delay, MCPWMXB = falling edge delay*/ MCPWM_ACTIVE_LOW_COMPLIMENT_MODE, /*!<MCPWMXA = compliment of rising edge delay, MCPWMXB = falling edge delay*/
MCPWM_ACTIVE_RED_FED_FROM_PWMXA, /*!<MCPWMXA = MCPWMXB = rising edge delay as well as falling edge delay, generated from MCPWMXA*/ MCPWM_ACTIVE_RED_FED_FROM_PWMXA, /*!<MCPWMXA = MCPWMXB = rising edge delay as well as falling edge delay, generated from MCPWMXA*/
MCPWM_ACTIVE_RED_FED_FROM_PWMXB, /*!<MCPWMXA = MCPWMXB = rising edge delay as well as falling edge delay, generated from MCPWMXB*/ MCPWM_ACTIVE_RED_FED_FROM_PWMXB, /*!<MCPWMXA = MCPWMXB = rising edge delay as well as falling edge delay, generated from MCPWMXB*/
MCPWM_DEADTIME_TYPE_MAX, MCPWM_DEADTIME_TYPE_MAX, /*!<Maximum number of supported dead time modes*/
} mcpwm_deadtime_type_t; } mcpwm_deadtime_type_t;
/** /**
@ -220,7 +218,7 @@ typedef mcpwm_output_action_t mcpwm_action_on_pwmxb_t;
* @brief MCPWM select capture signal input * @brief MCPWM select capture signal input
*/ */
typedef enum { typedef enum {
MCPWM_SELECT_CAP0 = 0, /*!<Select CAP0 as input*/ MCPWM_SELECT_CAP0, /*!<Select CAP0 as input*/
MCPWM_SELECT_CAP1, /*!<Select CAP1 as input*/ MCPWM_SELECT_CAP1, /*!<Select CAP1 as input*/
MCPWM_SELECT_CAP2, /*!<Select CAP2 as input*/ MCPWM_SELECT_CAP2, /*!<Select CAP2 as input*/
} mcpwm_capture_signal_t; } mcpwm_capture_signal_t;
@ -237,7 +235,7 @@ typedef struct {
} mcpwm_config_t; } mcpwm_config_t;
/** /**
* @brief MCPWM config carrier structure * @brief MCPWM carrier configuration structure
*/ */
typedef struct { typedef struct {
uint8_t carrier_period; /*!<Set carrier period = (carrier_period + 1)*800ns, carrier_period should be < 16*/ uint8_t carrier_period; /*!<Set carrier period = (carrier_period + 1)*800ns, carrier_period should be < 16*/
@ -249,8 +247,8 @@ typedef struct {
/** /**
* @brief This function initializes each gpio signal for MCPWM * @brief This function initializes each gpio signal for MCPWM
* @note *
* This function initializes one gpio at a time. * @note This function initializes one gpio at a time.
* *
* @param mcpwm_num set MCPWM unit(0-1) * @param mcpwm_num set MCPWM unit(0-1)
* @param io_signal set MCPWM signals, each MCPWM unit has 6 output(MCPWMXA, MCPWMXB) and 9 input(SYNC_X, FAULT_X, CAP_X) * @param io_signal set MCPWM signals, each MCPWM unit has 6 output(MCPWMXA, MCPWMXB) and 9 input(SYNC_X, FAULT_X, CAP_X)
@ -265,8 +263,8 @@ esp_err_t mcpwm_gpio_init(mcpwm_unit_t mcpwm_num, mcpwm_io_signals_t io_signal,
/** /**
* @brief Initialize MCPWM gpio structure * @brief Initialize MCPWM gpio structure
* @note *
* This function can be used to initialize more then one gpio at a time. * @note This function initialize a group of MCPWM GPIOs at a time.
* *
* @param mcpwm_num set MCPWM unit(0-1) * @param mcpwm_num set MCPWM unit(0-1)
* @param mcpwm_pin MCPWM pin structure * @param mcpwm_pin MCPWM pin structure
@ -619,20 +617,19 @@ esp_err_t mcpwm_fault_deinit(mcpwm_unit_t mcpwm_num, mcpwm_fault_signal_t fault_
/** /**
* @brief Initialize capture submodule * @brief Initialize capture submodule
* *
* @note Enabling capture feature could also enable the capture interrupt, * @note Enabling capture feature would also enable the capture interrupt event,
* users have to register an interrupt handler by `mcpwm_isr_register`, and in there, query the capture data. * users have to register an interrupt handler by `mcpwm_isr_register`, and in there, query the capture data.
* @note The capture timer uses APB_CLK (typically 80MHz) as the count source.
* *
* @param mcpwm_num set MCPWM unit(0-1) * @param mcpwm_num set MCPWM unit(0-1)
* @param cap_edge set capture edge, BIT(0) - negative edge, BIT(1) - positive edge * @param cap_edge set capture edge, BIT(0) - negative edge, BIT(1) - positive edge
* @param cap_sig capture pin, which needs to be enabled * @param cap_sig capture pin, which needs to be enabled
* @param num_of_pulse count time between rising/falling edge between 2 *(pulses mentioned), counter uses APB_CLK * @param num_of_pulse Input capture signal prescaling, num_of_pulse ranges from 0 to 255, representing prescaling from 1 to 256.
* [0~MCPWM_LL_MAX_PRESCALE] (MCPWM_LL_MAX_PRESCALE = 255 on ESP32);
* *
* @return * @return
* - ESP_OK Success * - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error * - ESP_ERR_INVALID_ARG Parameter error
*/ */
esp_err_t mcpwm_capture_enable(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig, mcpwm_capture_on_edge_t cap_edge, esp_err_t mcpwm_capture_enable(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t cap_sig, mcpwm_capture_on_edge_t cap_edge,
uint32_t num_of_pulse); uint32_t num_of_pulse);

View File

@ -35,7 +35,8 @@ static const char *TAG = "mcpwm";
#define MCPWM_GEN_ERROR "MCPWM GENERATOR ERROR" #define MCPWM_GEN_ERROR "MCPWM GENERATOR ERROR"
#define MCPWM_DT_ERROR "MCPWM DEADTIME TYPE ERROR" #define MCPWM_DT_ERROR "MCPWM DEADTIME TYPE ERROR"
#define MCPWM_GROUP_CLK_HZ (SOC_MCPWM_BASE_CLK_HZ / 16) #define MCPWM_GROUP_CLK_PRESCALE (16)
#define MCPWM_GROUP_CLK_HZ (SOC_MCPWM_BASE_CLK_HZ / MCPWM_GROUP_CLK_PRESCALE)
#define MCPWM_TIMER_CLK_HZ (MCPWM_GROUP_CLK_HZ / 10) #define MCPWM_TIMER_CLK_HZ (MCPWM_GROUP_CLK_HZ / 10)
_Static_assert(SOC_MCPWM_OPERATORS_PER_GROUP >= SOC_MCPWM_TIMERS_PER_GROUP, "This driver assumes the timer num equals to the operator num."); _Static_assert(SOC_MCPWM_OPERATORS_PER_GROUP >= SOC_MCPWM_TIMERS_PER_GROUP, "This driver assumes the timer num equals to the operator num.");
@ -100,12 +101,12 @@ esp_err_t mcpwm_gpio_init(mcpwm_unit_t mcpwm_num, mcpwm_io_signals_t io_signal,
esp_rom_gpio_connect_out_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].operators[operator_id].generators[generator_id].pwm_sig, 0, 0); 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 } else if (io_signal <= MCPWM_SYNC_2) { // External sync input signal
gpio_set_direction(gpio_num, GPIO_MODE_INPUT); gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
int ext_sync_id = io_signal - MCPWM_SYNC_0; int gpio_sync_id = io_signal - MCPWM_SYNC_0;
esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].ext_syncers[ext_sync_id].sync_sig, 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 } else if (io_signal <= MCPWM_FAULT_2) { // Fault input signal
gpio_set_direction(gpio_num, GPIO_MODE_INPUT); gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
int fault_id = io_signal - MCPWM_FAULT_0; int fault_id = io_signal - MCPWM_FAULT_0;
esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].detectors[fault_id].fault_sig, 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 } else if (io_signal >= MCPWM_CAP_0 && io_signal <= MCPWM_CAP_2) { // Capture input signal
gpio_set_direction(gpio_num, GPIO_MODE_INPUT); gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
int capture_id = io_signal - MCPWM_CAP_0; int capture_id = io_signal - MCPWM_CAP_0;
@ -141,7 +142,7 @@ esp_err_t mcpwm_start(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
MCPWM_TIMER_CHECK(mcpwm_num, timer_num); MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
mcpwm_critical_enter(mcpwm_num); mcpwm_critical_enter(mcpwm_num);
mcpwm_ll_timer_set_operate_command(context[mcpwm_num].hal.dev, timer_num, MCPWM_TIMER_START_NO_STOP); mcpwm_ll_timer_set_execute_command(context[mcpwm_num].hal.dev, timer_num, MCPWM_TIMER_START_NO_STOP);
mcpwm_critical_exit(mcpwm_num); mcpwm_critical_exit(mcpwm_num);
return ESP_OK; return ESP_OK;
} }
@ -151,7 +152,7 @@ esp_err_t mcpwm_stop(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
MCPWM_TIMER_CHECK(mcpwm_num, timer_num); MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
mcpwm_critical_enter(mcpwm_num); mcpwm_critical_enter(mcpwm_num);
mcpwm_ll_timer_set_operate_command(context[mcpwm_num].hal.dev, timer_num, MCPWM_TIMER_STOP_AT_ZERO); mcpwm_ll_timer_set_execute_command(context[mcpwm_num].hal.dev, timer_num, MCPWM_TIMER_STOP_AT_ZERO);
mcpwm_critical_exit(mcpwm_num); mcpwm_critical_exit(mcpwm_num);
return ESP_OK; return ESP_OK;
} }
@ -312,10 +313,10 @@ esp_err_t mcpwm_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpw
mcpwm_hal_init(hal, &config); mcpwm_hal_init(hal, &config);
mcpwm_critical_enter(mcpwm_num); mcpwm_critical_enter(mcpwm_num);
mcpwm_ll_group_set_clock(hal->dev, MCPWM_GROUP_CLK_HZ); mcpwm_ll_group_set_clock_prescale(hal->dev, MCPWM_GROUP_CLK_PRESCALE);
mcpwm_ll_group_enable_shadow_mode(hal->dev); mcpwm_ll_group_enable_shadow_mode(hal->dev);
mcpwm_ll_group_flush_shadow(hal->dev); mcpwm_ll_group_flush_shadow(hal->dev);
mcpwm_ll_timer_set_clock(hal->dev, timer_num, MCPWM_GROUP_CLK_HZ, MCPWM_TIMER_CLK_HZ); mcpwm_ll_timer_set_clock_prescale(hal->dev, timer_num, MCPWM_GROUP_CLK_HZ / MCPWM_TIMER_CLK_HZ);
mcpwm_ll_timer_set_count_mode(hal->dev, timer_num, mcpwm_conf->counter_mode); 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_update_period_at_once(hal->dev, timer_num);
mcpwm_ll_timer_set_peak(hal->dev, timer_num, MCPWM_TIMER_CLK_HZ / mcpwm_conf->frequency, false); mcpwm_ll_timer_set_peak(hal->dev, timer_num, MCPWM_TIMER_CLK_HZ / mcpwm_conf->frequency, false);
@ -336,8 +337,8 @@ uint32_t mcpwm_get_frequency(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num)
MCPWM_TIMER_CHECK(mcpwm_num, timer_num); MCPWM_TIMER_CHECK(mcpwm_num, timer_num);
mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
mcpwm_critical_enter(mcpwm_num); mcpwm_critical_enter(mcpwm_num);
unsigned long long group_clock = mcpwm_ll_group_get_clock(hal->dev); unsigned int group_clock = SOC_MCPWM_BASE_CLK_HZ / mcpwm_ll_group_get_clock_prescale(hal->dev);
unsigned long long timer_clock = mcpwm_ll_timer_get_clock(hal->dev, timer_num, group_clock); unsigned int timer_clock = group_clock / mcpwm_ll_timer_get_clock_prescale(hal->dev, timer_num);
mcpwm_critical_exit(mcpwm_num); mcpwm_critical_exit(mcpwm_num);
return (uint32_t)timer_clock; return (uint32_t)timer_clock;
} }
@ -479,7 +480,8 @@ esp_err_t mcpwm_deadtime_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num,
mcpwm_critical_enter(mcpwm_num); mcpwm_critical_enter(mcpwm_num);
mcpwm_ll_deadtime_enable_update_delay_on_tez(hal->dev, op, true); mcpwm_ll_deadtime_enable_update_delay_on_tez(hal->dev, op, true);
mcpwm_ll_deadtime_set_resolution_same_to_timer(hal->dev, op, false); // The dead time delay unit equals to MCPWM group resolution
mcpwm_ll_deadtime_resolution_to_timer(hal->dev, op, false);
mcpwm_ll_deadtime_set_rising_delay(hal->dev, op, red + 1); mcpwm_ll_deadtime_set_rising_delay(hal->dev, op, red + 1);
mcpwm_ll_deadtime_set_falling_delay(hal->dev, op, fed + 1); mcpwm_ll_deadtime_set_falling_delay(hal->dev, op, fed + 1);
switch (dt_mode) { switch (dt_mode) {
@ -611,11 +613,12 @@ esp_err_t mcpwm_fault_set_cyc_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_n
mcpwm_critical_enter(mcpwm_num); mcpwm_critical_enter(mcpwm_num);
mcpwm_ll_fault_enable_cbc_mode(hal->dev, op, fault_sig, true); mcpwm_ll_fault_enable_cbc_mode(hal->dev, op, fault_sig, true);
mcpwm_ll_fault_enable_cbc_refresh_on_tez(hal->dev, op, true);
mcpwm_ll_fault_enable_oneshot_mode(hal->dev, op, fault_sig, false); mcpwm_ll_fault_enable_oneshot_mode(hal->dev, op, fault_sig, false);
mcpwm_ll_generator_set_action_on_fault_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_FAULT_REACTION_CBC, action_on_pwmxa); mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TRIP_TYPE_CBC, action_on_pwmxa);
mcpwm_ll_generator_set_action_on_fault_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_UP, MCPWM_FAULT_REACTION_CBC, action_on_pwmxa); mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_UP, MCPWM_TRIP_TYPE_CBC, action_on_pwmxa);
mcpwm_ll_generator_set_action_on_fault_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_FAULT_REACTION_CBC, action_on_pwmxb); mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TRIP_TYPE_CBC, action_on_pwmxb);
mcpwm_ll_generator_set_action_on_fault_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_UP, MCPWM_FAULT_REACTION_CBC, action_on_pwmxb); mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_UP, MCPWM_TRIP_TYPE_CBC, action_on_pwmxb);
mcpwm_critical_exit(mcpwm_num); mcpwm_critical_exit(mcpwm_num);
return ESP_OK; return ESP_OK;
} }
@ -632,10 +635,10 @@ esp_err_t mcpwm_fault_set_oneshot_mode(mcpwm_unit_t mcpwm_num, mcpwm_timer_t tim
mcpwm_ll_fault_clear_ost(hal->dev, op); mcpwm_ll_fault_clear_ost(hal->dev, op);
mcpwm_ll_fault_enable_oneshot_mode(hal->dev, op, fault_sig, true); mcpwm_ll_fault_enable_oneshot_mode(hal->dev, op, fault_sig, true);
mcpwm_ll_fault_enable_cbc_mode(hal->dev, op, fault_sig, false); mcpwm_ll_fault_enable_cbc_mode(hal->dev, op, fault_sig, false);
mcpwm_ll_generator_set_action_on_fault_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_FAULT_REACTION_OST, action_on_pwmxa); mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TRIP_TYPE_OST, action_on_pwmxa);
mcpwm_ll_generator_set_action_on_fault_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_UP, MCPWM_FAULT_REACTION_OST, action_on_pwmxa); mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 0, MCPWM_TIMER_DIRECTION_UP, MCPWM_TRIP_TYPE_OST, action_on_pwmxa);
mcpwm_ll_generator_set_action_on_fault_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_FAULT_REACTION_OST, action_on_pwmxb); mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_DOWN, MCPWM_TRIP_TYPE_OST, action_on_pwmxb);
mcpwm_ll_generator_set_action_on_fault_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_UP, MCPWM_FAULT_REACTION_OST, action_on_pwmxb); mcpwm_ll_generator_set_action_on_trip_event(hal->dev, op, 1, MCPWM_TIMER_DIRECTION_UP, MCPWM_TRIP_TYPE_OST, action_on_pwmxb);
mcpwm_critical_exit(mcpwm_num); mcpwm_critical_exit(mcpwm_num);
return ESP_OK; return ESP_OK;
} }
@ -644,7 +647,7 @@ esp_err_t mcpwm_capture_enable(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t ca
uint32_t num_of_pulse) uint32_t num_of_pulse)
{ {
ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR); ESP_RETURN_ON_FALSE(mcpwm_num < SOC_MCPWM_GROUPS, ESP_ERR_INVALID_ARG, TAG, MCPWM_GROUP_NUM_ERROR);
ESP_RETURN_ON_FALSE(num_of_pulse <= MCPWM_LL_MAX_PRESCALE, ESP_ERR_INVALID_ARG, TAG, MCPWM_PRESCALE_ERROR); ESP_RETURN_ON_FALSE(num_of_pulse <= MCPWM_LL_MAX_CAPTURE_PRESCALE, ESP_ERR_INVALID_ARG, TAG, MCPWM_PRESCALE_ERROR);
ESP_RETURN_ON_FALSE(cap_sig < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR); ESP_RETURN_ON_FALSE(cap_sig < SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER, ESP_ERR_INVALID_ARG, TAG, MCPWM_CAPTURE_ERROR);
mcpwm_hal_context_t *hal = &context[mcpwm_num].hal; mcpwm_hal_context_t *hal = &context[mcpwm_num].hal;
// enable MCPWM module incase user don't use `mcpwm_init` at all // enable MCPWM module incase user don't use `mcpwm_init` at all
@ -654,7 +657,7 @@ esp_err_t mcpwm_capture_enable(mcpwm_unit_t mcpwm_num, mcpwm_capture_signal_t ca
}; };
mcpwm_critical_enter(mcpwm_num); mcpwm_critical_enter(mcpwm_num);
mcpwm_hal_init(hal, &init_config); mcpwm_hal_init(hal, &init_config);
mcpwm_ll_group_set_clock(hal->dev, MCPWM_GROUP_CLK_HZ); mcpwm_ll_group_set_clock_prescale(hal->dev, MCPWM_GROUP_CLK_PRESCALE);
mcpwm_ll_capture_enable_timer(hal->dev, true); mcpwm_ll_capture_enable_timer(hal->dev, true);
mcpwm_ll_capture_enable_channel(hal->dev, cap_sig, true); mcpwm_ll_capture_enable_channel(hal->dev, cap_sig, true);
mcpwm_ll_capture_enable_negedge(hal->dev, cap_sig, cap_edge & MCPWM_NEG_EDGE); mcpwm_ll_capture_enable_negedge(hal->dev, cap_sig, cap_edge & MCPWM_NEG_EDGE);
@ -707,9 +710,9 @@ esp_err_t mcpwm_sync_enable(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, mcp
uint32_t set_phase = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false) * phase_val / 1000; uint32_t set_phase = mcpwm_ll_timer_get_peak(hal->dev, timer_num, false) * phase_val / 1000;
mcpwm_ll_timer_set_sync_phase_value(hal->dev, timer_num, set_phase); mcpwm_ll_timer_set_sync_phase_value(hal->dev, timer_num, set_phase);
if (sync_sig >= MCPWM_SELECT_SYNC0) { if (sync_sig >= MCPWM_SELECT_SYNC0) {
mcpwm_ll_timer_enable_sync_from_external(hal->dev, timer_num, sync_sig - MCPWM_SELECT_SYNC0); mcpwm_ll_timer_set_timer_synchro(hal->dev, timer_num, sync_sig - MCPWM_SELECT_SYNC0);
} }
mcpwm_ll_timer_sync_out_same_in(hal->dev, timer_num); mcpwm_ll_timer_sync_out_penetrate(hal->dev, timer_num);
mcpwm_ll_timer_enable_sync_input(hal->dev, timer_num, true); mcpwm_ll_timer_enable_sync_input(hal->dev, timer_num, true);
mcpwm_critical_exit(mcpwm_num); mcpwm_critical_exit(mcpwm_num);
return ESP_OK; return ESP_OK;

View File

@ -52,12 +52,12 @@ static esp_err_t test_mcpwm_gpio_init(mcpwm_unit_t mcpwm_num, mcpwm_io_signals_t
esp_rom_gpio_connect_out_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].operators[operator_id].generators[generator_id].pwm_sig, 0, 0); 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 } else if (io_signal <= MCPWM_SYNC_2) { // External sync input signal
gpio_set_direction(gpio_num, GPIO_MODE_INPUT_OUTPUT); gpio_set_direction(gpio_num, GPIO_MODE_INPUT_OUTPUT);
int ext_sync_id = io_signal - MCPWM_SYNC_0; int gpio_sync_id = io_signal - MCPWM_SYNC_0;
esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].ext_syncers[ext_sync_id].sync_sig, 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 } else if (io_signal <= MCPWM_FAULT_2) { // Fault input signal
gpio_set_direction(gpio_num, GPIO_MODE_INPUT_OUTPUT); gpio_set_direction(gpio_num, GPIO_MODE_INPUT_OUTPUT);
int fault_id = io_signal - MCPWM_FAULT_0; int fault_id = io_signal - MCPWM_FAULT_0;
esp_rom_gpio_connect_in_signal(gpio_num, mcpwm_periph_signals.groups[mcpwm_num].detectors[fault_id].fault_sig, 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 } else if (io_signal >= MCPWM_CAP_0 && io_signal <= MCPWM_CAP_2) { // Capture input signal
gpio_set_direction(gpio_num, GPIO_MODE_INPUT_OUTPUT); gpio_set_direction(gpio_num, GPIO_MODE_INPUT_OUTPUT);
int capture_id = io_signal - MCPWM_CAP_0; int capture_id = io_signal - MCPWM_CAP_0;

View File

@ -26,6 +26,7 @@
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "soc/mcpwm_struct.h" #include "soc/mcpwm_struct.h"
#include "hal/mcpwm_types.h" #include "hal/mcpwm_types.h"
#include "hal/assert.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -33,24 +34,28 @@ extern "C" {
/// Get the address of peripheral registers /// Get the address of peripheral registers
#define MCPWM_LL_GET_HW(ID) (((ID) == 0) ? &MCPWM0 : &MCPWM1) #define MCPWM_LL_GET_HW(ID) (((ID) == 0) ? &MCPWM0 : &MCPWM1)
#define MCPWM_LL_MAX_PRESCALE 255 #define MCPWM_LL_MAX_CAPTURE_PRESCALE 255
#define MCPWM_LL_MAX_COMPARE_VALUE 65535
#define MCPWM_LL_MAX_DEAD_DELAY 65535
#define MCPWM_LL_MAX_PHASE_VALUE 65535
/********************* Group registers *******************/ /********************* Group registers *******************/
// Set/Get group clock: PWM_clk = CLK_160M / (prescale + 1) // Set/Get group clock: PWM_clk = CLK_160M / (prescale + 1)
static inline void mcpwm_ll_group_set_clock(mcpwm_dev_t *mcpwm, unsigned long long group_clk_hz) static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int pre_scale)
{ {
mcpwm->clk_cfg.prescale = (SOC_MCPWM_BASE_CLK_HZ / group_clk_hz) - 1; mcpwm->clk_cfg.prescale = pre_scale - 1;
} }
static inline unsigned long long mcpwm_ll_group_get_clock(mcpwm_dev_t *mcpwm) static inline uint32_t mcpwm_ll_group_get_clock_prescale(mcpwm_dev_t *mcpwm)
{ {
return SOC_MCPWM_BASE_CLK_HZ / (mcpwm->clk_cfg.prescale + 1); return mcpwm->clk_cfg.prescale + 1;
} }
static inline void mcpwm_ll_group_enable_shadow_mode(mcpwm_dev_t *mcpwm) static inline void mcpwm_ll_group_enable_shadow_mode(mcpwm_dev_t *mcpwm)
{ {
mcpwm->update_cfg.global_up_en = 1; mcpwm->update_cfg.global_up_en = 1;
// updating of active registers in MCPWM operators should be enabled
mcpwm->update_cfg.op0_up_en = 1; mcpwm->update_cfg.op0_up_en = 1;
mcpwm->update_cfg.op1_up_en = 1; mcpwm->update_cfg.op1_up_en = 1;
mcpwm->update_cfg.op2_up_en = 1; mcpwm->update_cfg.op2_up_en = 1;
@ -58,7 +63,8 @@ static inline void mcpwm_ll_group_enable_shadow_mode(mcpwm_dev_t *mcpwm)
static inline void mcpwm_ll_group_flush_shadow(mcpwm_dev_t *mcpwm) static inline void mcpwm_ll_group_flush_shadow(mcpwm_dev_t *mcpwm)
{ {
mcpwm->update_cfg.val ^= (1 << 1); // a toggle can trigger a forced update of all active registers in MCPWM, i.e. shadow->active
mcpwm->update_cfg.global_force_up = ~mcpwm->update_cfg.global_force_up;
} }
/********************* Interrupt registers *******************/ /********************* Interrupt registers *******************/
@ -129,47 +135,47 @@ static inline uint32_t mcpwm_ll_intr_get_capture_status(mcpwm_dev_t *mcpwm)
static inline void mcpwm_ll_intr_clear_timer_stop_status(mcpwm_dev_t *mcpwm, uint32_t timer_mask) static inline void mcpwm_ll_intr_clear_timer_stop_status(mcpwm_dev_t *mcpwm, uint32_t timer_mask)
{ {
mcpwm->int_clr.val |= (timer_mask & 0x07) << 0; mcpwm->int_clr.val = (timer_mask & 0x07) << 0;
} }
static inline void mcpwm_ll_intr_clear_timer_tez_status(mcpwm_dev_t *mcpwm, uint32_t timer_mask) static inline void mcpwm_ll_intr_clear_timer_tez_status(mcpwm_dev_t *mcpwm, uint32_t timer_mask)
{ {
mcpwm->int_clr.val |= (timer_mask & 0x07) << 3; mcpwm->int_clr.val = (timer_mask & 0x07) << 3;
} }
static inline void mcpwm_ll_intr_clear_timer_tep_status(mcpwm_dev_t *mcpwm, uint32_t timer_mask) static inline void mcpwm_ll_intr_clear_timer_tep_status(mcpwm_dev_t *mcpwm, uint32_t timer_mask)
{ {
mcpwm->int_clr.val |= (timer_mask & 0x07) << 6; mcpwm->int_clr.val = (timer_mask & 0x07) << 6;
} }
static inline void mcpwm_ll_intr_clear_fault_enter_status(mcpwm_dev_t *mcpwm, uint32_t fault_mask) static inline void mcpwm_ll_intr_clear_fault_enter_status(mcpwm_dev_t *mcpwm, uint32_t fault_mask)
{ {
mcpwm->int_clr.val |= (fault_mask & 0x07) << 9; mcpwm->int_clr.val = (fault_mask & 0x07) << 9;
} }
static inline void mcpwm_ll_intr_clear_fault_exit_status(mcpwm_dev_t *mcpwm, uint32_t fault_mask) static inline void mcpwm_ll_intr_clear_fault_exit_status(mcpwm_dev_t *mcpwm, uint32_t fault_mask)
{ {
mcpwm->int_clr.val |= (fault_mask & 0x07) << 12; mcpwm->int_clr.val = (fault_mask & 0x07) << 12;
} }
static inline void mcpwm_ll_intr_clear_compare_status(mcpwm_dev_t *mcpwm, uint32_t operator_mask, uint32_t cmp_id) static inline void mcpwm_ll_intr_clear_compare_status(mcpwm_dev_t *mcpwm, uint32_t operator_mask, uint32_t cmp_id)
{ {
mcpwm->int_clr.val |= (operator_mask & 0x07) << (15 + cmp_id * 3); mcpwm->int_clr.val = (operator_mask & 0x07) << (15 + cmp_id * 3);
} }
static inline void mcpwm_ll_intr_clear_trip_cbc_status(mcpwm_dev_t *mcpwm, uint32_t cbc_mask) static inline void mcpwm_ll_intr_clear_trip_cbc_status(mcpwm_dev_t *mcpwm, uint32_t cbc_mask)
{ {
mcpwm->int_clr.val |= (cbc_mask & 0x07) << 21; mcpwm->int_clr.val = (cbc_mask & 0x07) << 21;
} }
static inline void mcpwm_ll_intr_clear_trip_ost_status(mcpwm_dev_t *mcpwm, uint32_t ost_mask) static inline void mcpwm_ll_intr_clear_trip_ost_status(mcpwm_dev_t *mcpwm, uint32_t ost_mask)
{ {
mcpwm->int_clr.val |= (ost_mask & 0x07) << 24; mcpwm->int_clr.val = (ost_mask & 0x07) << 24;
} }
static inline void mcpwm_ll_intr_clear_capture_status(mcpwm_dev_t *mcpwm, uint32_t capture_mask) 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; mcpwm->int_clr.val = (capture_mask & 0x07) << 27;
} }
//////////// enable interrupt for each event //////////////// //////////// enable interrupt for each event ////////////////
@ -201,13 +207,20 @@ static inline void mcpwm_ll_intr_enable_timer_tep(mcpwm_dev_t *mcpwm, uint32_t t
} }
} }
static inline void mcpwm_ll_intr_enable_fault(mcpwm_dev_t *mcpwm, uint32_t fault_id, bool enable) static inline void mcpwm_ll_intr_enable_fault_enter(mcpwm_dev_t *mcpwm, uint32_t fault_id, bool enable)
{ {
if (enable) { if (enable) {
mcpwm->int_ena.val |= 1 << (9 + fault_id); // enter fault interrupt mcpwm->int_ena.val |= 1 << (9 + fault_id); // enter fault interrupt
mcpwm->int_ena.val |= 1 << (12 + fault_id); // exit fault interrupt
} else { } else {
mcpwm->int_ena.val &= ~(1 << (9 + fault_id)); mcpwm->int_ena.val &= ~(1 << (9 + fault_id));
}
}
static inline void mcpwm_ll_intr_enable_fault_exit(mcpwm_dev_t *mcpwm, uint32_t fault_id, bool enable)
{
if (enable) {
mcpwm->int_ena.val |= 1 << (12 + fault_id); // exit fault interrupt
} else {
mcpwm->int_ena.val &= ~(1 << (12 + fault_id)); mcpwm->int_ena.val &= ~(1 << (12 + fault_id));
} }
} }
@ -221,13 +234,20 @@ static inline void mcpwm_ll_intr_enable_compare(mcpwm_dev_t *mcpwm, uint32_t ope
} }
} }
static inline void mcpwm_ll_intr_enable_trip(mcpwm_dev_t *mcpwm, uint32_t operator_id, bool enable) static inline void mcpwm_ll_intr_enable_trip_cbc(mcpwm_dev_t *mcpwm, uint32_t operator_id, bool enable)
{ {
if (enable) { if (enable) {
mcpwm->int_ena.val |= (1 << (21 + operator_id)); mcpwm->int_ena.val |= (1 << (21 + operator_id));
mcpwm->int_ena.val |= (1 << (24 + operator_id));
} else { } else {
mcpwm->int_ena.val &= ~(1 << (21 + operator_id)); mcpwm->int_ena.val &= ~(1 << (21 + operator_id));
}
}
static inline void mcpwm_ll_intr_enable_trip_ost(mcpwm_dev_t *mcpwm, uint32_t operator_id, bool enable)
{
if (enable) {
mcpwm->int_ena.val |= (1 << (24 + operator_id));
} else {
mcpwm->int_ena.val &= ~(1 << (24 + operator_id)); mcpwm->int_ena.val &= ~(1 << (24 + operator_id));
} }
} }
@ -243,14 +263,14 @@ static inline void mcpwm_ll_intr_enable_capture(mcpwm_dev_t *mcpwm, uint32_t cap
/********************* Timer registers *******************/ /********************* Timer registers *******************/
static inline void mcpwm_ll_timer_set_clock(mcpwm_dev_t *mcpwm, int timer_id, unsigned long long group_clock, unsigned long long timer_clock) static inline void mcpwm_ll_timer_set_clock_prescale(mcpwm_dev_t *mcpwm, int timer_id, uint32_t prescale)
{ {
mcpwm->timer[timer_id].period.prescale = group_clock / timer_clock - 1; mcpwm->timer[timer_id].period.prescale = prescale - 1;
} }
static inline unsigned long long mcpwm_ll_timer_get_clock(mcpwm_dev_t *mcpwm, int timer_id, unsigned long long group_clock) static inline uint32_t mcpwm_ll_timer_get_clock_prescale(mcpwm_dev_t *mcpwm, int timer_id)
{ {
return group_clock / (mcpwm->timer[timer_id].period.prescale + 1); return mcpwm->timer[timer_id].period.prescale + 1;
} }
static inline void mcpwm_ll_timer_set_peak(mcpwm_dev_t *mcpwm, int timer_id, uint32_t peak, bool symmetric) static inline void mcpwm_ll_timer_set_peak(mcpwm_dev_t *mcpwm, int timer_id, uint32_t peak, bool symmetric)
@ -327,9 +347,9 @@ static inline mcpwm_timer_count_mode_t mcpwm_ll_timer_get_count_mode(mcpwm_dev_t
} }
} }
static inline void mcpwm_ll_timer_set_operate_command(mcpwm_dev_t *mcpwm, int timer_id, mcpwm_timer_operate_cmd_t mode) static inline void mcpwm_ll_timer_set_execute_command(mcpwm_dev_t *mcpwm, int timer_id, mcpwm_timer_execute_cmd_t cmd)
{ {
switch (mode) { switch (cmd) {
case MCPWM_TIMER_STOP_AT_ZERO: case MCPWM_TIMER_STOP_AT_ZERO:
mcpwm->timer[timer_id].mode.start = 0; mcpwm->timer[timer_id].mode.start = 0;
break; break;
@ -348,23 +368,14 @@ static inline void mcpwm_ll_timer_set_operate_command(mcpwm_dev_t *mcpwm, int ti
} }
} }
static inline void mcpwm_ll_timer_set_count_value(mcpwm_dev_t *mcpwm, int timer_id, uint32_t value)
{
// we use software sync to set count value
int previous_phase = mcpwm->timer[timer_id].sync.timer_phase;
mcpwm->timer[timer_id].sync.timer_phase = value;
mcpwm->timer[timer_id].sync.sync_sw = ~mcpwm->timer[timer_id].sync.sync_sw;
mcpwm->timer[timer_id].sync.timer_phase = previous_phase;
}
static inline uint32_t mcpwm_ll_timer_get_count_value(mcpwm_dev_t *mcpwm, int timer_id) static inline uint32_t mcpwm_ll_timer_get_count_value(mcpwm_dev_t *mcpwm, int timer_id)
{ {
return mcpwm->timer[timer_id].status.value; return mcpwm->timer[timer_id].status.value;
} }
static inline bool mcpwm_ll_is_timer_decreasing(mcpwm_dev_t *mcpwm, int timer_id) static inline mcpwm_timer_direction_t mcpwm_ll_timer_get_count_direction(mcpwm_dev_t *mcpwm, int timer_id)
{ {
return mcpwm->timer[timer_id].status.direction; return mcpwm->timer[timer_id].status.direction ? MCPWM_TIMER_DIRECTION_DOWN : MCPWM_TIMER_DIRECTION_UP;
} }
static inline void mcpwm_ll_timer_enable_sync_input(mcpwm_dev_t *mcpwm, int timer_id, bool enable) static inline void mcpwm_ll_timer_enable_sync_input(mcpwm_dev_t *mcpwm, int timer_id, bool enable)
@ -372,8 +383,9 @@ static inline void mcpwm_ll_timer_enable_sync_input(mcpwm_dev_t *mcpwm, int time
mcpwm->timer[timer_id].sync.in_en = enable; mcpwm->timer[timer_id].sync.in_en = enable;
} }
static inline void mcpwm_ll_timer_sync_out_same_in(mcpwm_dev_t *mcpwm, int timer_id) static inline void mcpwm_ll_timer_sync_out_penetrate(mcpwm_dev_t *mcpwm, int timer_id)
{ {
// sync_out is selected to sync_in
mcpwm->timer[timer_id].sync.out_sel = 0; mcpwm->timer[timer_id].sync.out_sel = 0;
} }
@ -383,47 +395,51 @@ static inline void mcpwm_ll_timer_sync_out_on_timer_event(mcpwm_dev_t *mcpwm, in
mcpwm->timer[timer_id].sync.out_sel = 1; mcpwm->timer[timer_id].sync.out_sel = 1;
} else if (event == MCPWM_TIMER_EVENT_PEAK) { } else if (event == MCPWM_TIMER_EVENT_PEAK) {
mcpwm->timer[timer_id].sync.out_sel = 2; mcpwm->timer[timer_id].sync.out_sel = 2;
} else {
HAL_ASSERT(false);
} }
} }
static inline void mcpwm_ll_timer_disable_sync_out(mcpwm_dev_t *mcpwm, int timer_id) static inline void mcpwm_ll_timer_disable_sync_out(mcpwm_dev_t *mcpwm, int timer_id)
{ {
// sync_out will always be zero
mcpwm->timer[timer_id].sync.out_sel = 3; mcpwm->timer[timer_id].sync.out_sel = 3;
} }
static inline void mcpwm_ll_timer_trigger_sw_sync(mcpwm_dev_t *mcpwm, int timer_id) static inline void mcpwm_ll_timer_trigger_soft_sync(mcpwm_dev_t *mcpwm, int timer_id)
{ {
mcpwm->timer[timer_id].sync.sync_sw = ~mcpwm->timer[timer_id].sync.sync_sw; mcpwm->timer[timer_id].sync.sync_sw = ~mcpwm->timer[timer_id].sync.sync_sw;
} }
static inline void mcpwm_ll_timer_set_sync_phase_value(mcpwm_dev_t *mcpwm, int timer_id, uint32_t reload_val) static inline void mcpwm_ll_timer_set_sync_phase_value(mcpwm_dev_t *mcpwm, int timer_id, uint32_t phase_value)
{ {
mcpwm->timer[timer_id].sync.timer_phase = reload_val; mcpwm->timer[timer_id].sync.timer_phase = phase_value;
} }
static inline uint32_t mcpwm_ll_timer_get_sync_phase_value(mcpwm_dev_t *mcpwm, int timer_id) static inline void mcpwm_ll_timer_set_sync_phase_direction(mcpwm_dev_t *mcpwm, int timer_id, mcpwm_timer_direction_t direction)
{ {
return mcpwm->timer[timer_id].sync.timer_phase; mcpwm->timer[timer_id].sync.phase_direct = direction;
} }
static inline void mcpwm_ll_timer_set_sync_phase_direction(mcpwm_dev_t *mcpwm, int timer_id, bool decrease) static inline void mcpwm_ll_timer_set_gpio_synchro(mcpwm_dev_t *mcpwm, int timer, int gpio_sync_id)
{ {
mcpwm->timer[timer_id].sync.phase_direct = decrease; mcpwm->timer_synci_cfg.val &= ~(0x07 << (timer * 3));
mcpwm->timer_synci_cfg.val |= (gpio_sync_id + 4) << (timer * 3);
} }
static inline void mcpwm_ll_timer_enable_sync_from_internal_timer(mcpwm_dev_t *mcpwm, int this_timer, int internal_sync_timer) static inline void mcpwm_ll_timer_set_timer_synchro(mcpwm_dev_t *mcpwm, int timer, int timer_sync_id)
{ {
mcpwm->timer_synci_cfg.val &= ~(0x07 << (this_timer * 3)); mcpwm->timer_synci_cfg.val &= ~(0x07 << (timer * 3));
mcpwm->timer_synci_cfg.val |= (internal_sync_timer + 1) << (this_timer * 3); mcpwm->timer_synci_cfg.val |= (timer_sync_id + 1) << (timer * 3);
} }
static inline void mcpwm_ll_timer_enable_sync_from_external(mcpwm_dev_t *mcpwm, int this_timer, int extern_syncer) static inline void mcpwm_ll_timer_set_soft_synchro(mcpwm_dev_t *mcpwm, int timer)
{ {
mcpwm->timer_synci_cfg.val &= ~(0x07 << (this_timer * 3)); // no sync input is selected, but software sync can still work
mcpwm->timer_synci_cfg.val |= (extern_syncer + 4) << (this_timer * 3); mcpwm->timer_synci_cfg.val &= ~(0x07 << (timer * 3));
} }
static inline void mcpwm_ll_invert_external_syncer(mcpwm_dev_t *mcpwm, int sync_id, bool invert) static inline void mcpwm_ll_invert_gpio_synchro(mcpwm_dev_t *mcpwm, int sync_id, bool invert)
{ {
if (invert) { if (invert) {
mcpwm->timer_synci_cfg.val |= 1 << (sync_id + 9); mcpwm->timer_synci_cfg.val |= 1 << (sync_id + 9);
@ -524,6 +540,19 @@ static inline void mcpwm_ll_operator_enable_update_action_on_sync(mcpwm_dev_t *m
} }
} }
static inline void mcpwm_ll_operator_set_trigger_gpio_fault(mcpwm_dev_t *mcpwm, int operator_id, int trig_id, int fault_id)
{
mcpwm->channel[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id));
mcpwm->channel[operator_id].gen_cfg0.val |= (fault_id << (4 + 3 * trig_id));
}
static inline void mcpwm_ll_operator_set_trigger_timer_sync(mcpwm_dev_t *mcpwm, int operator_id, int trig_id)
{
// the timer here is not selectable, must be the one connected with the operator
mcpwm->channel[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id));
mcpwm->channel[operator_id].gen_cfg0.val |= (3 << (4 + 3 * trig_id));
}
/********************* Generator registers *******************/ /********************* Generator registers *******************/
static inline void mcpwm_ll_generator_reset_actions(mcpwm_dev_t *mcpwm, int operator_id, int generator_id) static inline void mcpwm_ll_generator_reset_actions(mcpwm_dev_t *mcpwm, int operator_id, int generator_id)
@ -567,31 +596,58 @@ static inline void mcpwm_ll_generator_set_action_on_trigger_event(mcpwm_dev_t *m
} }
} }
static inline void mcpwm_ll_gen_set_onetime_force_action(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, int action) static inline void mcpwm_ll_gen_trigger_noncontinue_force_action(mcpwm_dev_t *mcpwm, int operator_id, int generator_id)
{ {
if (generator_id == 0) { if (generator_id == 0) {
mcpwm->channel[operator_id].gen_force.a_nciforce_mode = action;
mcpwm->channel[operator_id].gen_force.a_nciforce = ~mcpwm->channel[operator_id].gen_force.a_nciforce; mcpwm->channel[operator_id].gen_force.a_nciforce = ~mcpwm->channel[operator_id].gen_force.a_nciforce;
} else { } else {
mcpwm->channel[operator_id].gen_force.b_nciforce_mode = action;
mcpwm->channel[operator_id].gen_force.b_nciforce = ~mcpwm->channel[operator_id].gen_force.b_nciforce; mcpwm->channel[operator_id].gen_force.b_nciforce = ~mcpwm->channel[operator_id].gen_force.b_nciforce;
} }
} }
static inline void mcpwm_ll_gen_set_continuous_force_action(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, int action) static inline void mcpwm_ll_gen_disable_continue_force_action(mcpwm_dev_t *mcpwm, int operator_id, int generator_id)
{ {
mcpwm->channel[operator_id].gen_force.cntu_force_upmethod = 0; // force action immediately mcpwm->channel[operator_id].gen_force.cntu_force_upmethod = 0; // update force method immediately
if (generator_id == 0) { if (generator_id == 0) {
mcpwm->channel[operator_id].gen_force.a_cntuforce_mode = action; mcpwm->channel[operator_id].gen_force.a_cntuforce_mode = 0;
} else { } else {
mcpwm->channel[operator_id].gen_force.b_cntuforce_mode = action; mcpwm->channel[operator_id].gen_force.b_cntuforce_mode = 0;
}
}
static inline void mcpwm_ll_gen_disable_noncontinue_force_action(mcpwm_dev_t *mcpwm, int operator_id, int generator_id)
{
if (generator_id == 0) {
mcpwm->channel[operator_id].gen_force.a_nciforce_mode = 0;
} else {
mcpwm->channel[operator_id].gen_force.b_nciforce_mode = 0;
}
}
static inline void mcpwm_ll_gen_set_continue_force_level(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, int level)
{
mcpwm->channel[operator_id].gen_force.cntu_force_upmethod = 0; // update force method immediately
if (generator_id == 0) {
mcpwm->channel[operator_id].gen_force.a_cntuforce_mode = level + 1;
} else {
mcpwm->channel[operator_id].gen_force.b_cntuforce_mode = level + 1;
}
}
static inline void mcpwm_ll_gen_set_noncontinue_force_level(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, int level)
{
if (generator_id == 0) {
mcpwm->channel[operator_id].gen_force.a_nciforce_mode = level + 1;
} else {
mcpwm->channel[operator_id].gen_force.b_nciforce_mode = level + 1;
} }
} }
/********************* Dead time registers *******************/ /********************* Dead time registers *******************/
static inline void mcpwm_ll_deadtime_set_resolution_same_to_timer(mcpwm_dev_t *mcpwm, int operator_id, bool same) static inline void mcpwm_ll_deadtime_resolution_to_timer(mcpwm_dev_t *mcpwm, int operator_id, bool same)
{ {
// whether to make the resolution of dead time delay module the same to the timer connected with operator
mcpwm->channel[operator_id].db_cfg.clk_sel = same; mcpwm->channel[operator_id].db_cfg.clk_sel = same;
} }
@ -637,7 +693,7 @@ static inline void mcpwm_ll_deadtime_enable_deb(mcpwm_dev_t *mcpwm, int operator
mcpwm->channel[operator_id].db_cfg.deb_mode = enable; mcpwm->channel[operator_id].db_cfg.deb_mode = enable;
} }
static inline uint32_t mcpwm_ll_deadtime_get_topology_code(mcpwm_dev_t *mcpwm, int operator_id) static inline uint32_t mcpwm_ll_deadtime_get_switch_topology(mcpwm_dev_t *mcpwm, int operator_id)
{ {
return (mcpwm->channel[operator_id].db_cfg.deb_mode << 8) | (mcpwm->channel[operator_id].db_cfg.b_outswap << 7) | return (mcpwm->channel[operator_id].db_cfg.deb_mode << 8) | (mcpwm->channel[operator_id].db_cfg.b_outswap << 7) |
(mcpwm->channel[operator_id].db_cfg.a_outswap << 6) | (mcpwm->channel[operator_id].db_cfg.fed_insel << 5) | (mcpwm->channel[operator_id].db_cfg.a_outswap << 6) | (mcpwm->channel[operator_id].db_cfg.fed_insel << 5) |
@ -781,25 +837,32 @@ static inline void mcpwm_ll_fault_clear_ost(mcpwm_dev_t *mcpwm, int operator_id)
static inline void mcpwm_ll_fault_enable_oneshot_mode(mcpwm_dev_t *mcpwm, int operator_id, int fault_sig, bool enable) static inline void mcpwm_ll_fault_enable_oneshot_mode(mcpwm_dev_t *mcpwm, int operator_id, int fault_sig, bool enable)
{ {
if (fault_sig == 0) { mcpwm->channel[operator_id].tz_cfg0.val &= ~(1 << (7 - fault_sig));
mcpwm->channel[operator_id].tz_cfg0.f0_ost = enable; mcpwm->channel[operator_id].tz_cfg0.val |= (enable << (7 - fault_sig));
} else if (fault_sig == 1) {
mcpwm->channel[operator_id].tz_cfg0.f1_ost = enable;
} else {
mcpwm->channel[operator_id].tz_cfg0.f2_ost = enable;
}
} }
static inline void mcpwm_ll_fault_enable_cbc_mode(mcpwm_dev_t *mcpwm, int operator_id, int fault_sig, bool enable) static inline void mcpwm_ll_fault_enable_cbc_mode(mcpwm_dev_t *mcpwm, int operator_id, int fault_sig, bool enable)
{ {
if (fault_sig == 0) { mcpwm->channel[operator_id].tz_cfg0.val &= ~(1 << (3 - fault_sig));
mcpwm->channel[operator_id].tz_cfg0.f0_cbc = enable; mcpwm->channel[operator_id].tz_cfg0.val |= (enable << (3 - fault_sig));
} else if (fault_sig == 1) { }
mcpwm->channel[operator_id].tz_cfg0.f1_cbc = enable;
} else { static inline void mcpwm_ll_fault_enable_cbc_refresh_on_tez(mcpwm_dev_t *mcpwm, int operator_id, bool enable)
mcpwm->channel[operator_id].tz_cfg0.f2_cbc = enable; {
if (enable) {
mcpwm->channel[operator_id].tz_cfg1.val |= 1 << 1;
} else {
mcpwm->channel[operator_id].tz_cfg1.val &= ~(1 << 1);
}
}
static inline void mcpwm_ll_fault_enable_cbc_refresh_on_tep(mcpwm_dev_t *mcpwm, int operator_id, bool enable)
{
if (enable) {
mcpwm->channel[operator_id].tz_cfg1.val |= 1 << 2;
} else {
mcpwm->channel[operator_id].tz_cfg1.val &= ~(1 << 2);
} }
mcpwm->channel[operator_id].tz_cfg1.cbcpulse = 1 << 0;
} }
static inline void mcpwm_ll_fault_enable_sw_cbc(mcpwm_dev_t *mcpwm, int operator_id, bool enable) static inline void mcpwm_ll_fault_enable_sw_cbc(mcpwm_dev_t *mcpwm, int operator_id, bool enable)
@ -817,20 +880,20 @@ static inline void mcpwm_ll_fault_trigger_sw_cbc(mcpwm_dev_t *mcpwm, int operato
mcpwm->channel[operator_id].tz_cfg1.force_cbc = ~mcpwm->channel[operator_id].tz_cfg1.force_cbc; mcpwm->channel[operator_id].tz_cfg1.force_cbc = ~mcpwm->channel[operator_id].tz_cfg1.force_cbc;
} }
static inline void mcpwm_ll_fault_trigger_sw_oneshot(mcpwm_dev_t *mcpwm, int operator_id) static inline void mcpwm_ll_fault_trigger_sw_ost(mcpwm_dev_t *mcpwm, int operator_id)
{ {
mcpwm->channel[operator_id].tz_cfg1.force_ost = ~mcpwm->channel[operator_id].tz_cfg1.force_ost; mcpwm->channel[operator_id].tz_cfg1.force_ost = ~mcpwm->channel[operator_id].tz_cfg1.force_ost;
} }
static inline void mcpwm_ll_generator_set_action_on_fault_event(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, static inline void mcpwm_ll_generator_set_action_on_trip_event(mcpwm_dev_t *mcpwm, int operator_id, int generator_id,
mcpwm_timer_direction_t direction, mcpwm_fault_reaction_t reaction, int action) mcpwm_timer_direction_t direction, mcpwm_trip_type_t trip, int action)
{ {
if (direction == MCPWM_TIMER_DIRECTION_UP) { if (direction == MCPWM_TIMER_DIRECTION_UP) {
mcpwm->channel[operator_id].tz_cfg0.val &= ~(0x03 << (8 + 8 * generator_id + 4 * reaction + 2)); mcpwm->channel[operator_id].tz_cfg0.val &= ~(0x03 << (8 + 8 * generator_id + 4 * trip + 2));
mcpwm->channel[operator_id].tz_cfg0.val |= action << (8 + 8 * generator_id + 4 * reaction + 2); mcpwm->channel[operator_id].tz_cfg0.val |= action << (8 + 8 * generator_id + 4 * trip + 2);
} else if (direction == MCPWM_TIMER_DIRECTION_DOWN) { } else if (direction == MCPWM_TIMER_DIRECTION_DOWN) {
mcpwm->channel[operator_id].tz_cfg0.val &= ~(0x03 << (8 + 8 * generator_id + 4 * reaction)); mcpwm->channel[operator_id].tz_cfg0.val &= ~(0x03 << (8 + 8 * generator_id + 4 * trip));
mcpwm->channel[operator_id].tz_cfg0.val |= action << (8 + 8 * generator_id + 4 * reaction); mcpwm->channel[operator_id].tz_cfg0.val |= action << (8 + 8 * generator_id + 4 * trip);
} }
} }
@ -856,12 +919,12 @@ static inline void mcpwm_ll_capture_enable_channel(mcpwm_dev_t *mcpwm, int chann
mcpwm->cap_cfg_ch[channel].en = enable; mcpwm->cap_cfg_ch[channel].en = enable;
} }
static inline void mcpwm_ll_capture_set_sync_phase(mcpwm_dev_t *mcpwm, uint32_t phase_value) static inline void mcpwm_ll_capture_set_sync_phase_value(mcpwm_dev_t *mcpwm, uint32_t phase_value)
{ {
mcpwm->cap_timer_phase = phase_value; mcpwm->cap_timer_phase = phase_value;
} }
static inline uint32_t mcpwm_ll_capture_get_sync_phase(mcpwm_dev_t *mcpwm) static inline uint32_t mcpwm_ll_capture_get_sync_phase_value(mcpwm_dev_t *mcpwm)
{ {
return mcpwm->cap_timer_phase; return mcpwm->cap_timer_phase;
} }
@ -871,14 +934,14 @@ static inline void mcpwm_ll_capture_enable_timer_sync(mcpwm_dev_t *mcpwm, bool e
mcpwm->cap_timer_cfg.synci_en = enable; mcpwm->cap_timer_cfg.synci_en = enable;
} }
static inline void mcpwm_ll_capture_set_internal_timer_syncer(mcpwm_dev_t *mcpwm, int sync_out_timer) static inline void mcpwm_ll_capture_set_internal_timer_synchro(mcpwm_dev_t *mcpwm, int sync_out_timer)
{ {
mcpwm->cap_timer_cfg.synci_sel = sync_out_timer + 1; mcpwm->cap_timer_cfg.synci_sel = sync_out_timer + 1;
} }
static inline void mcpwm_ll_capture_set_external_syncer(mcpwm_dev_t *mcpwm, int extern_syncer) static inline void mcpwm_ll_capture_set_external_synchro(mcpwm_dev_t *mcpwm, int extern_synchro)
{ {
mcpwm->cap_timer_cfg.synci_sel = extern_syncer + 4; mcpwm->cap_timer_cfg.synci_sel = extern_synchro + 4;
} }
static inline void mcpwm_ll_capture_trigger_sw_sync(mcpwm_dev_t *mcpwm) static inline void mcpwm_ll_capture_trigger_sw_sync(mcpwm_dev_t *mcpwm)

View File

@ -26,6 +26,7 @@
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "soc/mcpwm_struct.h" #include "soc/mcpwm_struct.h"
#include "hal/mcpwm_types.h" #include "hal/mcpwm_types.h"
#include "hal/assert.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -33,24 +34,28 @@ extern "C" {
/// Get the address of peripheral registers /// Get the address of peripheral registers
#define MCPWM_LL_GET_HW(ID) (((ID) == 0) ? &MCPWM0 : &MCPWM1) #define MCPWM_LL_GET_HW(ID) (((ID) == 0) ? &MCPWM0 : &MCPWM1)
#define MCPWM_LL_MAX_PRESCALE 255 #define MCPWM_LL_MAX_CAPTURE_PRESCALE 255
#define MCPWM_LL_MAX_COMPARE_VALUE 65535
#define MCPWM_LL_MAX_DEAD_DELAY 65535
#define MCPWM_LL_MAX_PHASE_VALUE 65535
/********************* Group registers *******************/ /********************* Group registers *******************/
// Set/Get group clock: PWM_clk = CLK_160M / (prescale + 1) // Set/Get group clock: PWM_clk = CLK_160M / (prescale + 1)
static inline void mcpwm_ll_group_set_clock(mcpwm_dev_t *mcpwm, unsigned long long group_clk_hz) static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int pre_scale)
{ {
mcpwm->clk_cfg.prescale = (SOC_MCPWM_BASE_CLK_HZ / group_clk_hz) - 1; mcpwm->clk_cfg.prescale = pre_scale - 1;
} }
static inline unsigned long long mcpwm_ll_group_get_clock(mcpwm_dev_t *mcpwm) static inline uint32_t mcpwm_ll_group_get_clock_prescale(mcpwm_dev_t *mcpwm)
{ {
return SOC_MCPWM_BASE_CLK_HZ / (mcpwm->clk_cfg.prescale + 1); return mcpwm->clk_cfg.prescale + 1;
} }
static inline void mcpwm_ll_group_enable_shadow_mode(mcpwm_dev_t *mcpwm) static inline void mcpwm_ll_group_enable_shadow_mode(mcpwm_dev_t *mcpwm)
{ {
mcpwm->update_cfg.global_up_en = 1; mcpwm->update_cfg.global_up_en = 1;
// updating of active registers in MCPWM operators should be enabled
mcpwm->update_cfg.op0_up_en = 1; mcpwm->update_cfg.op0_up_en = 1;
mcpwm->update_cfg.op1_up_en = 1; mcpwm->update_cfg.op1_up_en = 1;
mcpwm->update_cfg.op2_up_en = 1; mcpwm->update_cfg.op2_up_en = 1;
@ -58,7 +63,8 @@ static inline void mcpwm_ll_group_enable_shadow_mode(mcpwm_dev_t *mcpwm)
static inline void mcpwm_ll_group_flush_shadow(mcpwm_dev_t *mcpwm) static inline void mcpwm_ll_group_flush_shadow(mcpwm_dev_t *mcpwm)
{ {
mcpwm->update_cfg.val ^= (1 << 1); // a toggle can trigger a forced update of all active registers in MCPWM, i.e. shadow->active
mcpwm->update_cfg.global_force_up = ~mcpwm->update_cfg.global_force_up;
} }
/********************* Interrupt registers *******************/ /********************* Interrupt registers *******************/
@ -129,47 +135,47 @@ static inline uint32_t mcpwm_ll_intr_get_capture_status(mcpwm_dev_t *mcpwm)
static inline void mcpwm_ll_intr_clear_timer_stop_status(mcpwm_dev_t *mcpwm, uint32_t timer_mask) static inline void mcpwm_ll_intr_clear_timer_stop_status(mcpwm_dev_t *mcpwm, uint32_t timer_mask)
{ {
mcpwm->int_clr.val |= (timer_mask & 0x07) << 0; mcpwm->int_clr.val = (timer_mask & 0x07) << 0;
} }
static inline void mcpwm_ll_intr_clear_timer_tez_status(mcpwm_dev_t *mcpwm, uint32_t timer_mask) static inline void mcpwm_ll_intr_clear_timer_tez_status(mcpwm_dev_t *mcpwm, uint32_t timer_mask)
{ {
mcpwm->int_clr.val |= (timer_mask & 0x07) << 3; mcpwm->int_clr.val = (timer_mask & 0x07) << 3;
} }
static inline void mcpwm_ll_intr_clear_timer_tep_status(mcpwm_dev_t *mcpwm, uint32_t timer_mask) static inline void mcpwm_ll_intr_clear_timer_tep_status(mcpwm_dev_t *mcpwm, uint32_t timer_mask)
{ {
mcpwm->int_clr.val |= (timer_mask & 0x07) << 6; mcpwm->int_clr.val = (timer_mask & 0x07) << 6;
} }
static inline void mcpwm_ll_intr_clear_fault_enter_status(mcpwm_dev_t *mcpwm, uint32_t fault_mask) static inline void mcpwm_ll_intr_clear_fault_enter_status(mcpwm_dev_t *mcpwm, uint32_t fault_mask)
{ {
mcpwm->int_clr.val |= (fault_mask & 0x07) << 9; mcpwm->int_clr.val = (fault_mask & 0x07) << 9;
} }
static inline void mcpwm_ll_intr_clear_fault_exit_status(mcpwm_dev_t *mcpwm, uint32_t fault_mask) static inline void mcpwm_ll_intr_clear_fault_exit_status(mcpwm_dev_t *mcpwm, uint32_t fault_mask)
{ {
mcpwm->int_clr.val |= (fault_mask & 0x07) << 12; mcpwm->int_clr.val = (fault_mask & 0x07) << 12;
} }
static inline void mcpwm_ll_intr_clear_compare_status(mcpwm_dev_t *mcpwm, uint32_t operator_mask, uint32_t cmp_id) static inline void mcpwm_ll_intr_clear_compare_status(mcpwm_dev_t *mcpwm, uint32_t operator_mask, uint32_t cmp_id)
{ {
mcpwm->int_clr.val |= (operator_mask & 0x07) << (15 + cmp_id * 3); mcpwm->int_clr.val = (operator_mask & 0x07) << (15 + cmp_id * 3);
} }
static inline void mcpwm_ll_intr_clear_trip_cbc_status(mcpwm_dev_t *mcpwm, uint32_t cbc_mask) static inline void mcpwm_ll_intr_clear_trip_cbc_status(mcpwm_dev_t *mcpwm, uint32_t cbc_mask)
{ {
mcpwm->int_clr.val |= (cbc_mask & 0x07) << 21; mcpwm->int_clr.val = (cbc_mask & 0x07) << 21;
} }
static inline void mcpwm_ll_intr_clear_trip_ost_status(mcpwm_dev_t *mcpwm, uint32_t ost_mask) static inline void mcpwm_ll_intr_clear_trip_ost_status(mcpwm_dev_t *mcpwm, uint32_t ost_mask)
{ {
mcpwm->int_clr.val |= (ost_mask & 0x07) << 24; mcpwm->int_clr.val = (ost_mask & 0x07) << 24;
} }
static inline void mcpwm_ll_intr_clear_capture_status(mcpwm_dev_t *mcpwm, uint32_t capture_mask) 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; mcpwm->int_clr.val = (capture_mask & 0x07) << 27;
} }
//////////// enable interrupt for each event //////////////// //////////// enable interrupt for each event ////////////////
@ -201,13 +207,20 @@ static inline void mcpwm_ll_intr_enable_timer_tep(mcpwm_dev_t *mcpwm, uint32_t t
} }
} }
static inline void mcpwm_ll_intr_enable_fault(mcpwm_dev_t *mcpwm, uint32_t fault_id, bool enable) static inline void mcpwm_ll_intr_enable_fault_enter(mcpwm_dev_t *mcpwm, uint32_t fault_id, bool enable)
{ {
if (enable) { if (enable) {
mcpwm->int_ena.val |= 1 << (9 + fault_id); // enter fault interrupt mcpwm->int_ena.val |= 1 << (9 + fault_id); // enter fault interrupt
mcpwm->int_ena.val |= 1 << (12 + fault_id); // exit fault interrupt
} else { } else {
mcpwm->int_ena.val &= ~(1 << (9 + fault_id)); mcpwm->int_ena.val &= ~(1 << (9 + fault_id));
}
}
static inline void mcpwm_ll_intr_enable_fault_exit(mcpwm_dev_t *mcpwm, uint32_t fault_id, bool enable)
{
if (enable) {
mcpwm->int_ena.val |= 1 << (12 + fault_id); // exit fault interrupt
} else {
mcpwm->int_ena.val &= ~(1 << (12 + fault_id)); mcpwm->int_ena.val &= ~(1 << (12 + fault_id));
} }
} }
@ -221,13 +234,20 @@ static inline void mcpwm_ll_intr_enable_compare(mcpwm_dev_t *mcpwm, uint32_t ope
} }
} }
static inline void mcpwm_ll_intr_enable_trip(mcpwm_dev_t *mcpwm, uint32_t operator_id, bool enable) static inline void mcpwm_ll_intr_enable_trip_cbc(mcpwm_dev_t *mcpwm, uint32_t operator_id, bool enable)
{ {
if (enable) { if (enable) {
mcpwm->int_ena.val |= (1 << (21 + operator_id)); mcpwm->int_ena.val |= (1 << (21 + operator_id));
mcpwm->int_ena.val |= (1 << (24 + operator_id));
} else { } else {
mcpwm->int_ena.val &= ~(1 << (21 + operator_id)); mcpwm->int_ena.val &= ~(1 << (21 + operator_id));
}
}
static inline void mcpwm_ll_intr_enable_trip_ost(mcpwm_dev_t *mcpwm, uint32_t operator_id, bool enable)
{
if (enable) {
mcpwm->int_ena.val |= (1 << (24 + operator_id));
} else {
mcpwm->int_ena.val &= ~(1 << (24 + operator_id)); mcpwm->int_ena.val &= ~(1 << (24 + operator_id));
} }
} }
@ -243,14 +263,14 @@ static inline void mcpwm_ll_intr_enable_capture(mcpwm_dev_t *mcpwm, uint32_t cap
/********************* Timer registers *******************/ /********************* Timer registers *******************/
static inline void mcpwm_ll_timer_set_clock(mcpwm_dev_t *mcpwm, int timer_id, unsigned long long group_clock, unsigned long long timer_clock) static inline void mcpwm_ll_timer_set_clock_prescale(mcpwm_dev_t *mcpwm, int timer_id, uint32_t prescale)
{ {
mcpwm->timer[timer_id].period.prescale = group_clock / timer_clock - 1; mcpwm->timer[timer_id].period.prescale = prescale - 1;
} }
static inline unsigned long long mcpwm_ll_timer_get_clock(mcpwm_dev_t *mcpwm, int timer_id, unsigned long long group_clock) static inline uint32_t mcpwm_ll_timer_get_clock_prescale(mcpwm_dev_t *mcpwm, int timer_id)
{ {
return group_clock / (mcpwm->timer[timer_id].period.prescale + 1); return mcpwm->timer[timer_id].period.prescale + 1;
} }
static inline void mcpwm_ll_timer_set_peak(mcpwm_dev_t *mcpwm, int timer_id, uint32_t peak, bool symmetric) static inline void mcpwm_ll_timer_set_peak(mcpwm_dev_t *mcpwm, int timer_id, uint32_t peak, bool symmetric)
@ -327,9 +347,9 @@ static inline mcpwm_timer_count_mode_t mcpwm_ll_timer_get_count_mode(mcpwm_dev_t
} }
} }
static inline void mcpwm_ll_timer_set_operate_command(mcpwm_dev_t *mcpwm, int timer_id, mcpwm_timer_operate_cmd_t mode) static inline void mcpwm_ll_timer_set_execute_command(mcpwm_dev_t *mcpwm, int timer_id, mcpwm_timer_execute_cmd_t cmd)
{ {
switch (mode) { switch (cmd) {
case MCPWM_TIMER_STOP_AT_ZERO: case MCPWM_TIMER_STOP_AT_ZERO:
mcpwm->timer[timer_id].mode.start = 0; mcpwm->timer[timer_id].mode.start = 0;
break; break;
@ -348,23 +368,23 @@ static inline void mcpwm_ll_timer_set_operate_command(mcpwm_dev_t *mcpwm, int ti
} }
} }
static inline void mcpwm_ll_timer_set_count_value(mcpwm_dev_t *mcpwm, int timer_id, uint32_t value)
{
// we use software sync to set count value
int previous_phase = mcpwm->timer[timer_id].sync.timer_phase;
mcpwm->timer[timer_id].sync.timer_phase = value;
mcpwm->timer[timer_id].sync.sync_sw = ~mcpwm->timer[timer_id].sync.sync_sw;
mcpwm->timer[timer_id].sync.timer_phase = previous_phase;
}
static inline uint32_t mcpwm_ll_timer_get_count_value(mcpwm_dev_t *mcpwm, int timer_id) static inline uint32_t mcpwm_ll_timer_get_count_value(mcpwm_dev_t *mcpwm, int timer_id)
{ {
// status.value saves the "next count value", so need an extra round up here to get the current count value according to count mode
// timer is paused
if (mcpwm->timer[timer_id].mode.mode == 0) {
return mcpwm->timer[timer_id].status.value; return mcpwm->timer[timer_id].status.value;
} }
if (mcpwm->timer[timer_id].status.direction) { // down direction
return (mcpwm->timer[timer_id].status.value + 1) % (mcpwm->timer[timer_id].period.period + 1);
}
// up direction
return (mcpwm->timer[timer_id].status.value + mcpwm->timer[timer_id].period.period) % (mcpwm->timer[timer_id].period.period + 1);
}
static inline bool mcpwm_ll_is_timer_decreasing(mcpwm_dev_t *mcpwm, int timer_id) static inline mcpwm_timer_direction_t mcpwm_ll_timer_get_count_direction(mcpwm_dev_t *mcpwm, int timer_id)
{ {
return mcpwm->timer[timer_id].status.direction; return mcpwm->timer[timer_id].status.direction ? MCPWM_TIMER_DIRECTION_DOWN : MCPWM_TIMER_DIRECTION_UP;
} }
static inline void mcpwm_ll_timer_enable_sync_input(mcpwm_dev_t *mcpwm, int timer_id, bool enable) static inline void mcpwm_ll_timer_enable_sync_input(mcpwm_dev_t *mcpwm, int timer_id, bool enable)
@ -372,8 +392,9 @@ static inline void mcpwm_ll_timer_enable_sync_input(mcpwm_dev_t *mcpwm, int time
mcpwm->timer[timer_id].sync.in_en = enable; mcpwm->timer[timer_id].sync.in_en = enable;
} }
static inline void mcpwm_ll_timer_sync_out_same_in(mcpwm_dev_t *mcpwm, int timer_id) static inline void mcpwm_ll_timer_sync_out_penetrate(mcpwm_dev_t *mcpwm, int timer_id)
{ {
// sync_out is selected to sync_in
mcpwm->timer[timer_id].sync.out_sel = 0; mcpwm->timer[timer_id].sync.out_sel = 0;
} }
@ -383,47 +404,51 @@ static inline void mcpwm_ll_timer_sync_out_on_timer_event(mcpwm_dev_t *mcpwm, in
mcpwm->timer[timer_id].sync.out_sel = 1; mcpwm->timer[timer_id].sync.out_sel = 1;
} else if (event == MCPWM_TIMER_EVENT_PEAK) { } else if (event == MCPWM_TIMER_EVENT_PEAK) {
mcpwm->timer[timer_id].sync.out_sel = 2; mcpwm->timer[timer_id].sync.out_sel = 2;
} else {
HAL_ASSERT(false);
} }
} }
static inline void mcpwm_ll_timer_disable_sync_out(mcpwm_dev_t *mcpwm, int timer_id) static inline void mcpwm_ll_timer_disable_sync_out(mcpwm_dev_t *mcpwm, int timer_id)
{ {
// sync_out will always be zero
mcpwm->timer[timer_id].sync.out_sel = 3; mcpwm->timer[timer_id].sync.out_sel = 3;
} }
static inline void mcpwm_ll_timer_trigger_sw_sync(mcpwm_dev_t *mcpwm, int timer_id) static inline void mcpwm_ll_timer_trigger_soft_sync(mcpwm_dev_t *mcpwm, int timer_id)
{ {
mcpwm->timer[timer_id].sync.sync_sw = ~mcpwm->timer[timer_id].sync.sync_sw; mcpwm->timer[timer_id].sync.sync_sw = ~mcpwm->timer[timer_id].sync.sync_sw;
} }
static inline void mcpwm_ll_timer_set_sync_phase_value(mcpwm_dev_t *mcpwm, int timer_id, uint32_t reload_val) static inline void mcpwm_ll_timer_set_sync_phase_value(mcpwm_dev_t *mcpwm, int timer_id, uint32_t phase_value)
{ {
mcpwm->timer[timer_id].sync.timer_phase = reload_val; mcpwm->timer[timer_id].sync.timer_phase = phase_value;
} }
static inline uint32_t mcpwm_ll_timer_get_sync_phase_value(mcpwm_dev_t *mcpwm, int timer_id) static inline void mcpwm_ll_timer_set_sync_phase_direction(mcpwm_dev_t *mcpwm, int timer_id, mcpwm_timer_direction_t direction)
{ {
return mcpwm->timer[timer_id].sync.timer_phase; mcpwm->timer[timer_id].sync.phase_direct = direction;
} }
static inline void mcpwm_ll_timer_set_sync_phase_direction(mcpwm_dev_t *mcpwm, int timer_id, bool decrease) static inline void mcpwm_ll_timer_set_gpio_synchro(mcpwm_dev_t *mcpwm, int timer, int gpio_sync_id)
{ {
mcpwm->timer[timer_id].sync.phase_direct = decrease; mcpwm->timer_synci_cfg.val &= ~(0x07 << (timer * 3));
mcpwm->timer_synci_cfg.val |= (gpio_sync_id + 4) << (timer * 3);
} }
static inline void mcpwm_ll_timer_enable_sync_from_internal_timer(mcpwm_dev_t *mcpwm, int this_timer, int internal_sync_timer) static inline void mcpwm_ll_timer_set_timer_synchro(mcpwm_dev_t *mcpwm, int timer, int timer_sync_id)
{ {
mcpwm->timer_synci_cfg.val &= ~(0x07 << (this_timer * 3)); mcpwm->timer_synci_cfg.val &= ~(0x07 << (timer * 3));
mcpwm->timer_synci_cfg.val |= (internal_sync_timer + 1) << (this_timer * 3); mcpwm->timer_synci_cfg.val |= (timer_sync_id + 1) << (timer * 3);
} }
static inline void mcpwm_ll_timer_enable_sync_from_external(mcpwm_dev_t *mcpwm, int this_timer, int extern_syncer) static inline void mcpwm_ll_timer_set_soft_synchro(mcpwm_dev_t *mcpwm, int timer)
{ {
mcpwm->timer_synci_cfg.val &= ~(0x07 << (this_timer * 3)); // no sync input is selected, but software sync can still work
mcpwm->timer_synci_cfg.val |= (extern_syncer + 4) << (this_timer * 3); mcpwm->timer_synci_cfg.val &= ~(0x07 << (timer * 3));
} }
static inline void mcpwm_ll_invert_external_syncer(mcpwm_dev_t *mcpwm, int sync_id, bool invert) static inline void mcpwm_ll_invert_gpio_synchro(mcpwm_dev_t *mcpwm, int sync_id, bool invert)
{ {
if (invert) { if (invert) {
mcpwm->timer_synci_cfg.val |= 1 << (sync_id + 9); mcpwm->timer_synci_cfg.val |= 1 << (sync_id + 9);
@ -524,6 +549,19 @@ static inline void mcpwm_ll_operator_enable_update_action_on_sync(mcpwm_dev_t *m
} }
} }
static inline void mcpwm_ll_operator_set_trigger_gpio_fault(mcpwm_dev_t *mcpwm, int operator_id, int trig_id, int fault_id)
{
mcpwm->channel[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id));
mcpwm->channel[operator_id].gen_cfg0.val |= (fault_id << (4 + 3 * trig_id));
}
static inline void mcpwm_ll_operator_set_trigger_timer_sync(mcpwm_dev_t *mcpwm, int operator_id, int trig_id)
{
// the timer here is not selectable, must be the one connected with the operator
mcpwm->channel[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id));
mcpwm->channel[operator_id].gen_cfg0.val |= (3 << (4 + 3 * trig_id));
}
/********************* Generator registers *******************/ /********************* Generator registers *******************/
static inline void mcpwm_ll_generator_reset_actions(mcpwm_dev_t *mcpwm, int operator_id, int generator_id) static inline void mcpwm_ll_generator_reset_actions(mcpwm_dev_t *mcpwm, int operator_id, int generator_id)
@ -567,31 +605,58 @@ static inline void mcpwm_ll_generator_set_action_on_trigger_event(mcpwm_dev_t *m
} }
} }
static inline void mcpwm_ll_gen_set_onetime_force_action(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, int action) static inline void mcpwm_ll_gen_trigger_noncontinue_force_action(mcpwm_dev_t *mcpwm, int operator_id, int generator_id)
{ {
if (generator_id == 0) { if (generator_id == 0) {
mcpwm->channel[operator_id].gen_force.a_nciforce_mode = action;
mcpwm->channel[operator_id].gen_force.a_nciforce = ~mcpwm->channel[operator_id].gen_force.a_nciforce; mcpwm->channel[operator_id].gen_force.a_nciforce = ~mcpwm->channel[operator_id].gen_force.a_nciforce;
} else { } else {
mcpwm->channel[operator_id].gen_force.b_nciforce_mode = action;
mcpwm->channel[operator_id].gen_force.b_nciforce = ~mcpwm->channel[operator_id].gen_force.b_nciforce; mcpwm->channel[operator_id].gen_force.b_nciforce = ~mcpwm->channel[operator_id].gen_force.b_nciforce;
} }
} }
static inline void mcpwm_ll_gen_set_continuous_force_action(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, int action) static inline void mcpwm_ll_gen_disable_continue_force_action(mcpwm_dev_t *mcpwm, int operator_id, int generator_id)
{ {
mcpwm->channel[operator_id].gen_force.cntu_force_upmethod = 0; // force action immediately mcpwm->channel[operator_id].gen_force.cntu_force_upmethod = 0; // update force method immediately
if (generator_id == 0) { if (generator_id == 0) {
mcpwm->channel[operator_id].gen_force.a_cntuforce_mode = action; mcpwm->channel[operator_id].gen_force.a_cntuforce_mode = 0;
} else { } else {
mcpwm->channel[operator_id].gen_force.b_cntuforce_mode = action; mcpwm->channel[operator_id].gen_force.b_cntuforce_mode = 0;
}
}
static inline void mcpwm_ll_gen_disable_noncontinue_force_action(mcpwm_dev_t *mcpwm, int operator_id, int generator_id)
{
if (generator_id == 0) {
mcpwm->channel[operator_id].gen_force.a_nciforce_mode = 0;
} else {
mcpwm->channel[operator_id].gen_force.b_nciforce_mode = 0;
}
}
static inline void mcpwm_ll_gen_set_continue_force_level(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, int level)
{
mcpwm->channel[operator_id].gen_force.cntu_force_upmethod = 0; // update force method immediately
if (generator_id == 0) {
mcpwm->channel[operator_id].gen_force.a_cntuforce_mode = level + 1;
} else {
mcpwm->channel[operator_id].gen_force.b_cntuforce_mode = level + 1;
}
}
static inline void mcpwm_ll_gen_set_noncontinue_force_level(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, int level)
{
if (generator_id == 0) {
mcpwm->channel[operator_id].gen_force.a_nciforce_mode = level + 1;
} else {
mcpwm->channel[operator_id].gen_force.b_nciforce_mode = level + 1;
} }
} }
/********************* Dead time registers *******************/ /********************* Dead time registers *******************/
static inline void mcpwm_ll_deadtime_set_resolution_same_to_timer(mcpwm_dev_t *mcpwm, int operator_id, bool same) static inline void mcpwm_ll_deadtime_resolution_to_timer(mcpwm_dev_t *mcpwm, int operator_id, bool same)
{ {
// whether to make the resolution of dead time delay module the same to the timer connected with operator
mcpwm->channel[operator_id].db_cfg.clk_sel = same; mcpwm->channel[operator_id].db_cfg.clk_sel = same;
} }
@ -637,7 +702,7 @@ static inline void mcpwm_ll_deadtime_enable_deb(mcpwm_dev_t *mcpwm, int operator
mcpwm->channel[operator_id].db_cfg.deb_mode = enable; mcpwm->channel[operator_id].db_cfg.deb_mode = enable;
} }
static inline uint32_t mcpwm_ll_deadtime_get_topology_code(mcpwm_dev_t *mcpwm, int operator_id) static inline uint32_t mcpwm_ll_deadtime_get_switch_topology(mcpwm_dev_t *mcpwm, int operator_id)
{ {
return (mcpwm->channel[operator_id].db_cfg.deb_mode << 8) | (mcpwm->channel[operator_id].db_cfg.b_outswap << 7) | return (mcpwm->channel[operator_id].db_cfg.deb_mode << 8) | (mcpwm->channel[operator_id].db_cfg.b_outswap << 7) |
(mcpwm->channel[operator_id].db_cfg.a_outswap << 6) | (mcpwm->channel[operator_id].db_cfg.fed_insel << 5) | (mcpwm->channel[operator_id].db_cfg.a_outswap << 6) | (mcpwm->channel[operator_id].db_cfg.fed_insel << 5) |
@ -781,25 +846,32 @@ static inline void mcpwm_ll_fault_clear_ost(mcpwm_dev_t *mcpwm, int operator_id)
static inline void mcpwm_ll_fault_enable_oneshot_mode(mcpwm_dev_t *mcpwm, int operator_id, int fault_sig, bool enable) static inline void mcpwm_ll_fault_enable_oneshot_mode(mcpwm_dev_t *mcpwm, int operator_id, int fault_sig, bool enable)
{ {
if (fault_sig == 0) { mcpwm->channel[operator_id].tz_cfg0.val &= ~(1 << (7 - fault_sig));
mcpwm->channel[operator_id].tz_cfg0.f0_ost = enable; mcpwm->channel[operator_id].tz_cfg0.val |= (enable << (7 - fault_sig));
} else if (fault_sig == 1) {
mcpwm->channel[operator_id].tz_cfg0.f1_ost = enable;
} else {
mcpwm->channel[operator_id].tz_cfg0.f2_ost = enable;
}
} }
static inline void mcpwm_ll_fault_enable_cbc_mode(mcpwm_dev_t *mcpwm, int operator_id, int fault_sig, bool enable) static inline void mcpwm_ll_fault_enable_cbc_mode(mcpwm_dev_t *mcpwm, int operator_id, int fault_sig, bool enable)
{ {
if (fault_sig == 0) { mcpwm->channel[operator_id].tz_cfg0.val &= ~(1 << (3 - fault_sig));
mcpwm->channel[operator_id].tz_cfg0.f0_cbc = enable; mcpwm->channel[operator_id].tz_cfg0.val |= (enable << (3 - fault_sig));
} else if (fault_sig == 1) { }
mcpwm->channel[operator_id].tz_cfg0.f1_cbc = enable;
} else { static inline void mcpwm_ll_fault_enable_cbc_refresh_on_tez(mcpwm_dev_t *mcpwm, int operator_id, bool enable)
mcpwm->channel[operator_id].tz_cfg0.f2_cbc = enable; {
if (enable) {
mcpwm->channel[operator_id].tz_cfg1.val |= 1 << 1;
} else {
mcpwm->channel[operator_id].tz_cfg1.val &= ~(1 << 1);
}
}
static inline void mcpwm_ll_fault_enable_cbc_refresh_on_tep(mcpwm_dev_t *mcpwm, int operator_id, bool enable)
{
if (enable) {
mcpwm->channel[operator_id].tz_cfg1.val |= 1 << 2;
} else {
mcpwm->channel[operator_id].tz_cfg1.val &= ~(1 << 2);
} }
mcpwm->channel[operator_id].tz_cfg1.cbcpulse = 1 << 0;
} }
static inline void mcpwm_ll_fault_enable_sw_cbc(mcpwm_dev_t *mcpwm, int operator_id, bool enable) static inline void mcpwm_ll_fault_enable_sw_cbc(mcpwm_dev_t *mcpwm, int operator_id, bool enable)
@ -817,20 +889,20 @@ static inline void mcpwm_ll_fault_trigger_sw_cbc(mcpwm_dev_t *mcpwm, int operato
mcpwm->channel[operator_id].tz_cfg1.force_cbc = ~mcpwm->channel[operator_id].tz_cfg1.force_cbc; mcpwm->channel[operator_id].tz_cfg1.force_cbc = ~mcpwm->channel[operator_id].tz_cfg1.force_cbc;
} }
static inline void mcpwm_ll_fault_trigger_sw_oneshot(mcpwm_dev_t *mcpwm, int operator_id) static inline void mcpwm_ll_fault_trigger_sw_ost(mcpwm_dev_t *mcpwm, int operator_id)
{ {
mcpwm->channel[operator_id].tz_cfg1.force_ost = ~mcpwm->channel[operator_id].tz_cfg1.force_ost; mcpwm->channel[operator_id].tz_cfg1.force_ost = ~mcpwm->channel[operator_id].tz_cfg1.force_ost;
} }
static inline void mcpwm_ll_generator_set_action_on_fault_event(mcpwm_dev_t *mcpwm, int operator_id, int generator_id, static inline void mcpwm_ll_generator_set_action_on_trip_event(mcpwm_dev_t *mcpwm, int operator_id, int generator_id,
mcpwm_timer_direction_t direction, mcpwm_fault_reaction_t reaction, int action) mcpwm_timer_direction_t direction, mcpwm_trip_type_t trip, int action)
{ {
if (direction == MCPWM_TIMER_DIRECTION_UP) { if (direction == MCPWM_TIMER_DIRECTION_UP) {
mcpwm->channel[operator_id].tz_cfg0.val &= ~(0x03 << (8 + 8 * generator_id + 4 * reaction + 2)); mcpwm->channel[operator_id].tz_cfg0.val &= ~(0x03 << (8 + 8 * generator_id + 4 * trip + 2));
mcpwm->channel[operator_id].tz_cfg0.val |= action << (8 + 8 * generator_id + 4 * reaction + 2); mcpwm->channel[operator_id].tz_cfg0.val |= action << (8 + 8 * generator_id + 4 * trip + 2);
} else if (direction == MCPWM_TIMER_DIRECTION_DOWN) { } else if (direction == MCPWM_TIMER_DIRECTION_DOWN) {
mcpwm->channel[operator_id].tz_cfg0.val &= ~(0x03 << (8 + 8 * generator_id + 4 * reaction)); mcpwm->channel[operator_id].tz_cfg0.val &= ~(0x03 << (8 + 8 * generator_id + 4 * trip));
mcpwm->channel[operator_id].tz_cfg0.val |= action << (8 + 8 * generator_id + 4 * reaction); mcpwm->channel[operator_id].tz_cfg0.val |= action << (8 + 8 * generator_id + 4 * trip);
} }
} }
@ -856,12 +928,12 @@ static inline void mcpwm_ll_capture_enable_channel(mcpwm_dev_t *mcpwm, int chann
mcpwm->cap_cfg_ch[channel].en = enable; mcpwm->cap_cfg_ch[channel].en = enable;
} }
static inline void mcpwm_ll_capture_set_sync_phase(mcpwm_dev_t *mcpwm, uint32_t phase_value) static inline void mcpwm_ll_capture_set_sync_phase_value(mcpwm_dev_t *mcpwm, uint32_t phase_value)
{ {
mcpwm->cap_timer_phase = phase_value; mcpwm->cap_timer_phase = phase_value;
} }
static inline uint32_t mcpwm_ll_capture_get_sync_phase(mcpwm_dev_t *mcpwm) static inline uint32_t mcpwm_ll_capture_get_sync_phase_value(mcpwm_dev_t *mcpwm)
{ {
return mcpwm->cap_timer_phase; return mcpwm->cap_timer_phase;
} }
@ -871,14 +943,14 @@ static inline void mcpwm_ll_capture_enable_timer_sync(mcpwm_dev_t *mcpwm, bool e
mcpwm->cap_timer_cfg.synci_en = enable; mcpwm->cap_timer_cfg.synci_en = enable;
} }
static inline void mcpwm_ll_capture_set_internal_timer_syncer(mcpwm_dev_t *mcpwm, int sync_out_timer) static inline void mcpwm_ll_capture_set_internal_timer_synchro(mcpwm_dev_t *mcpwm, int sync_out_timer)
{ {
mcpwm->cap_timer_cfg.synci_sel = sync_out_timer + 1; mcpwm->cap_timer_cfg.synci_sel = sync_out_timer + 1;
} }
static inline void mcpwm_ll_capture_set_external_syncer(mcpwm_dev_t *mcpwm, int extern_syncer) static inline void mcpwm_ll_capture_set_external_synchro(mcpwm_dev_t *mcpwm, int extern_synchro)
{ {
mcpwm->cap_timer_cfg.synci_sel = extern_syncer + 4; mcpwm->cap_timer_cfg.synci_sel = extern_synchro + 4;
} }
static inline void mcpwm_ll_capture_trigger_sw_sync(mcpwm_dev_t *mcpwm) static inline void mcpwm_ll_capture_trigger_sw_sync(mcpwm_dev_t *mcpwm)

View File

@ -37,7 +37,7 @@ typedef enum {
MCPWM_TIMER_START_NO_STOP, /*!< MCPWM timer starts couting */ MCPWM_TIMER_START_NO_STOP, /*!< MCPWM timer starts couting */
MCPWM_TIMER_START_STOP_AT_ZERO, /*!< MCPWM timer starts counting and stops when couting to zero */ MCPWM_TIMER_START_STOP_AT_ZERO, /*!< MCPWM timer starts counting and stops when couting to zero */
MCPWM_TIMER_START_STOP_AT_PEAK, /*!< MCPWM timer starts counting and stops when counting to peak */ MCPWM_TIMER_START_STOP_AT_PEAK, /*!< MCPWM timer starts counting and stops when counting to peak */
} mcpwm_timer_operate_cmd_t; } mcpwm_timer_execute_cmd_t;
typedef enum { typedef enum {
MCPWM_GEN_ACTION_KEEP, /*!< Generator action: Keep the same level */ MCPWM_GEN_ACTION_KEEP, /*!< Generator action: Keep the same level */
@ -47,6 +47,6 @@ typedef enum {
} mcpwm_generator_action_t; } mcpwm_generator_action_t;
typedef enum { typedef enum {
MCPWM_FAULT_REACTION_CBC, /*!< Reaction on fault signal: recover cycle by cycle */ MCPWM_TRIP_TYPE_CBC, /*!< CBC trip type, shut down the operator cycle by cycle*/
MCPWM_FAULT_REACTION_OST, /*!< Reaction on fault signal: one shot trip */ MCPWM_TRIP_TYPE_OST, /*!< OST trip type, shut down the operator in one shot */
} mcpwm_fault_reaction_t; } mcpwm_trip_type_t;

View File

@ -236,26 +236,8 @@
#define PWM1_CAP1_IN_IDX 113 #define PWM1_CAP1_IN_IDX 113
#define PWM1_OUT2B_IDX 113 #define PWM1_OUT2B_IDX 113
#define PWM1_CAP2_IN_IDX 114 #define PWM1_CAP2_IN_IDX 114
#define PWM2_OUT1H_IDX 114
#define PWM2_FLTA_IDX 115
#define PWM2_OUT1L_IDX 115
#define PWM2_FLTB_IDX 116
#define PWM2_OUT2H_IDX 116
#define PWM2_CAP1_IN_IDX 117
#define PWM2_OUT2L_IDX 117
#define PWM2_CAP2_IN_IDX 118
#define PWM2_OUT3H_IDX 118
#define PWM2_CAP3_IN_IDX 119
#define PWM2_OUT3L_IDX 119
#define PWM3_FLTA_IDX 120
#define PWM2_OUT4H_IDX 120
#define PWM3_FLTB_IDX 121
#define PWM2_OUT4L_IDX 121
#define PWM3_CAP1_IN_IDX 122
#define PWM3_CAP2_IN_IDX 123
#define TWAI_TX_IDX 123 #define TWAI_TX_IDX 123
#define CAN_TX_IDX TWAI_TX_IDX #define CAN_TX_IDX TWAI_TX_IDX
#define PWM3_CAP3_IN_IDX 124
#define TWAI_BUS_OFF_ON_IDX 124 #define TWAI_BUS_OFF_ON_IDX 124
#define CAN_BUS_OFF_ON_IDX TWAI_BUS_OFF_ON_IDX #define CAN_BUS_OFF_ON_IDX TWAI_BUS_OFF_ON_IDX
#define TWAI_CLKOUT_IDX 125 #define TWAI_CLKOUT_IDX 125
@ -369,19 +351,11 @@
#define I2S1O_DATA_OUT22_IDX 188 #define I2S1O_DATA_OUT22_IDX 188
#define I2S1O_DATA_OUT23_IDX 189 #define I2S1O_DATA_OUT23_IDX 189
#define I2S0I_H_SYNC_IDX 190 #define I2S0I_H_SYNC_IDX 190
#define PWM3_OUT1H_IDX 190
#define I2S0I_V_SYNC_IDX 191 #define I2S0I_V_SYNC_IDX 191
#define PWM3_OUT1L_IDX 191
#define I2S0I_H_ENABLE_IDX 192 #define I2S0I_H_ENABLE_IDX 192
#define PWM3_OUT2H_IDX 192
#define I2S1I_H_SYNC_IDX 193 #define I2S1I_H_SYNC_IDX 193
#define PWM3_OUT2L_IDX 193
#define I2S1I_V_SYNC_IDX 194 #define I2S1I_V_SYNC_IDX 194
#define PWM3_OUT3H_IDX 194
#define I2S1I_H_ENABLE_IDX 195 #define I2S1I_H_ENABLE_IDX 195
#define PWM3_OUT3L_IDX 195
#define PWM3_OUT4H_IDX 196
#define PWM3_OUT4L_IDX 197
#define U2RXD_IN_IDX 198 #define U2RXD_IN_IDX 198
#define U2TXD_OUT_IDX 198 #define U2TXD_OUT_IDX 198
#define U2CTS_IN_IDX 199 #define U2CTS_IN_IDX 199

View File

@ -158,10 +158,11 @@
#define SOC_MCPWM_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has #define SOC_MCPWM_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has
#define SOC_MCPWM_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has #define SOC_MCPWM_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has
#define SOC_MCPWM_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has #define SOC_MCPWM_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has
#define SOC_MCPWM_FAULT_DETECTORS_PER_GROUP (3) ///< The number of fault signal detectors that each group has #define SOC_MCPWM_TRIGGERS_PER_OPERATOR (2) ///< The number of triggers that each operator has
#define SOC_MCPWM_GPIO_FAULTS_PER_GROUP (3) ///< The number of GPIO fault signals that each group has
#define SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has #define SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has
#define SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has #define SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has
#define SOC_MCPWM_EXT_SYNCERS_PER_GROUP (3) ///< The number of external syncers that each group has #define SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP (3) ///< The number of GPIO synchros that each group has
#define SOC_MCPWM_BASE_CLK_HZ (160000000ULL) ///< Base Clock frequency of 160MHz #define SOC_MCPWM_BASE_CLK_HZ (160000000ULL) ///< Base Clock frequency of 160MHz
/*-------------------------- MPU CAPS ----------------------------------------*/ /*-------------------------- MPU CAPS ----------------------------------------*/

View File

@ -53,7 +53,7 @@ const mcpwm_signal_conn_t mcpwm_periph_signals = {
} }
} }
}, },
.detectors = { .gpio_faults = {
[0] = { [0] = {
.fault_sig = PWM0_F0_IN_IDX .fault_sig = PWM0_F0_IN_IDX
}, },
@ -75,7 +75,7 @@ const mcpwm_signal_conn_t mcpwm_periph_signals = {
.cap_sig = PWM0_CAP2_IN_IDX .cap_sig = PWM0_CAP2_IN_IDX
} }
}, },
.ext_syncers = { .gpio_synchros = {
[0] = { [0] = {
.sync_sig = PWM0_SYNC0_IN_IDX .sync_sig = PWM0_SYNC0_IN_IDX
}, },
@ -122,7 +122,7 @@ const mcpwm_signal_conn_t mcpwm_periph_signals = {
} }
} }
}, },
.detectors = { .gpio_faults = {
[0] = { [0] = {
.fault_sig = PWM1_F0_IN_IDX .fault_sig = PWM1_F0_IN_IDX
}, },
@ -144,7 +144,7 @@ const mcpwm_signal_conn_t mcpwm_periph_signals = {
.cap_sig = PWM1_CAP2_IN_IDX .cap_sig = PWM1_CAP2_IN_IDX
} }
}, },
.ext_syncers = { .gpio_synchros = {
[0] = { [0] = {
.sync_sig = PWM1_SYNC0_IN_IDX .sync_sig = PWM1_SYNC0_IN_IDX
}, },

View File

@ -69,10 +69,11 @@
#define SOC_MCPWM_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has #define SOC_MCPWM_OPERATORS_PER_GROUP (3) ///< The number of operators that each group has
#define SOC_MCPWM_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has #define SOC_MCPWM_COMPARATORS_PER_OPERATOR (2) ///< The number of comparators that each operator has
#define SOC_MCPWM_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has #define SOC_MCPWM_GENERATORS_PER_OPERATOR (2) ///< The number of generators that each operator has
#define SOC_MCPWM_FAULT_DETECTORS_PER_GROUP (3) ///< The number of fault signal detectors that each group has #define SOC_MCPWM_TRIGGERS_PER_OPERATOR (2) ///< The number of triggers that each operator has
#define SOC_MCPWM_GPIO_FAULTS_PER_GROUP (3) ///< The number of fault signal detectors that each group has
#define SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has #define SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP (1) ///< The number of capture timers that each group has
#define SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has #define SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER (3) ///< The number of capture channels that each capture timer has
#define SOC_MCPWM_EXT_SYNCERS_PER_GROUP (3) ///< The number of external syncers that each group has #define SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP (3) ///< The number of GPIO synchros that each group has
#define SOC_MCPWM_BASE_CLK_HZ (160000000ULL) ///< Base Clock frequency of 160MHz #define SOC_MCPWM_BASE_CLK_HZ (160000000ULL) ///< Base Clock frequency of 160MHz
/*-------------------------- MPU CAPS ----------------------------------------*/ /*-------------------------- MPU CAPS ----------------------------------------*/

View File

@ -53,7 +53,7 @@ const mcpwm_signal_conn_t mcpwm_periph_signals = {
} }
} }
}, },
.detectors = { .gpio_faults = {
[0] = { [0] = {
.fault_sig = PWM0_F0_IN_IDX .fault_sig = PWM0_F0_IN_IDX
}, },
@ -75,7 +75,7 @@ const mcpwm_signal_conn_t mcpwm_periph_signals = {
.cap_sig = PWM0_CAP2_IN_IDX .cap_sig = PWM0_CAP2_IN_IDX
} }
}, },
.ext_syncers = { .gpio_synchros = {
[0] = { [0] = {
.sync_sig = PWM0_SYNC0_IN_IDX .sync_sig = PWM0_SYNC0_IN_IDX
}, },
@ -122,7 +122,7 @@ const mcpwm_signal_conn_t mcpwm_periph_signals = {
} }
} }
}, },
.detectors = { .gpio_faults = {
[0] = { [0] = {
.fault_sig = PWM1_F0_IN_IDX .fault_sig = PWM1_F0_IN_IDX
}, },
@ -144,7 +144,7 @@ const mcpwm_signal_conn_t mcpwm_periph_signals = {
.cap_sig = PWM1_CAP2_IN_IDX .cap_sig = PWM1_CAP2_IN_IDX
} }
}, },
.ext_syncers = { .gpio_synchros = {
[0] = { [0] = {
.sync_sig = PWM1_SYNC0_IN_IDX .sync_sig = PWM1_SYNC0_IN_IDX
}, },

View File

@ -34,13 +34,13 @@ typedef struct {
} operators[SOC_MCPWM_OPERATORS_PER_GROUP]; } operators[SOC_MCPWM_OPERATORS_PER_GROUP];
struct { struct {
const uint32_t fault_sig; const uint32_t fault_sig;
} detectors[SOC_MCPWM_FAULT_DETECTORS_PER_GROUP]; } gpio_faults[SOC_MCPWM_GPIO_FAULTS_PER_GROUP];
struct { struct {
const uint32_t cap_sig; const uint32_t cap_sig;
} captures[SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER]; } captures[SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER];
struct { struct {
const uint32_t sync_sig; const uint32_t sync_sig;
} ext_syncers[SOC_MCPWM_EXT_SYNCERS_PER_GROUP]; } gpio_synchros[SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP];
} groups[SOC_MCPWM_GROUPS]; } groups[SOC_MCPWM_GROUPS];
} mcpwm_signal_conn_t; } mcpwm_signal_conn_t;