OVMS3-idf/components/soc/esp32/include/hal/mcpwm_ll.h

727 lines
23 KiB
C

// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
// The LL layer for ESP32 MCPWM register operations
#pragma once
#include <soc/mcpwm_periph.h>
#include "soc/mcpwm_periph.h"
#include "hal/mcpwm_types.h"
#include "soc/mcpwm_caps.h"
#include "hal/hal_defs.h"
#include "esp_types.h"
/// Get the address of peripheral registers
#define MCPWM_LL_GET_HW(ID) (((ID)==0)? &MCPWM0: &MCPWM1)
/********************* Global *******************/
/**
* Initialize common registers.
*
* @param mcpwm Address of the MCPWM peripheral registers.
*/
static inline void mcpwm_ll_init(mcpwm_dev_t *mcpwm)
{
mcpwm->update_cfg.global_up_en = 1;
mcpwm->update_cfg.global_force_up = 1;
mcpwm->update_cfg.global_force_up = 0;
}
/**
* Set the prescale of the PWM main clock to the input clock.
*
* Input clock is 160MHz, PWM main clock cycle = 6.25ns*(prescale + 1).
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param prescale Prescale factor, 0-255.
*/
static inline void mcpwm_ll_set_clock_prescale(mcpwm_dev_t *mcpwm, int prescale)
{
mcpwm->clk_cfg.prescale = prescale;
}
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_LL_INTR_CAP0, MCPWM_CAP0_INT_RAW);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_LL_INTR_CAP1, MCPWM_CAP1_INT_RAW);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_LL_INTR_CAP2, MCPWM_CAP2_INT_RAW);
/**
* Get raw interrupt status.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @return The triggered interrupts, ORed by active interrupts.
*/
static inline mcpwm_intr_t mcpwm_ll_get_intr(mcpwm_dev_t *mcpwm)
{
return mcpwm->int_raw.val;
}
/**
* Clear the interrupts.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param intr Bitwise ORed interrupts to clear.
*/
static inline void mcpwm_ll_clear_intr(mcpwm_dev_t* mcpwm, mcpwm_intr_t intr)
{
mcpwm->int_clr.val = intr;
}
/********************* Timer *******************/
/**
* Set the prescale of the Timer_x clock to the PWM main clock.
*
* Timer clock frequency = PWM main clock frequency/(prescale + 1).
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to set the prescale, 0-2.
* @param prescale Prescale factor, 0-255.
*/
static inline void mcpwm_ll_timer_set_prescale(mcpwm_dev_t* mcpwm, int timer, uint32_t prescale)
{
mcpwm->timer[timer].period.prescale = prescale;
}
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_UP_COUNTER, 1);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_DOWN_COUNTER, 2);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_UP_DOWN_COUNTER, 3);
/**
* Set the counting mode for the PWM timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to change counting mode, 0-2.
* @param mode Counting mode to use.
*/
static inline void mcpwm_ll_timer_set_count_mode(mcpwm_dev_t *mcpwm, int timer, mcpwm_counter_type_t mode)
{
mcpwm->timer[timer].mode.mode = mode;
}
/**
* Start a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to start, 0-2.
*/
static inline void mcpwm_ll_timer_start(mcpwm_dev_t *mcpwm, int timer)
{
mcpwm->timer[timer].mode.start = 2;
}
/**
* Stop a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to stop, 0-2.
*/
static inline void mcpwm_ll_timer_stop(mcpwm_dev_t *mcpwm, int timer)
{
mcpwm->timer[timer].mode.start = 0;
}
/**
* Set the overflow period of a timer.
*
* The overflow rate will be Frequency of timer / period.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to set period, 0-2.
* @param period Total timer count of each period, 0-65535.
*/
static inline void mcpwm_ll_timer_set_period(mcpwm_dev_t *mcpwm, int timer, uint32_t period)
{
mcpwm->timer[timer].period.period = period - 1;
mcpwm->timer[timer].period.upmethod = 0;
}
/**
* Get the period setting of a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to get the period, 0-2.
* @return Period setting value.
*/
static inline uint32_t mcpwm_ll_timer_get_period(mcpwm_dev_t *mcpwm, int timer)
{
return mcpwm->timer[timer].period.period + 1;
}
/********************* Sync *******************/
/**
* Enable the synchronization feature for a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer Timer to set, 0-2.
* @param enable true to enable, otherwise false.
*/
static inline void mcpwm_ll_sync_enable(mcpwm_dev_t *mcpwm, int timer, bool enable)
{
if (enable) {
mcpwm->timer[timer].sync.out_sel = 0;
mcpwm->timer[timer].sync.in_en = 1;
} else {
mcpwm->timer[timer].sync.in_en = 0;
}
}
/**
* Set the phase (counter value) to reload when the sync signal triggers.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer Timer to set, 0-2.
* @param reload_val The reloaded value.
*/
static inline void mcpwm_ll_sync_set_phase(mcpwm_dev_t *mcpwm, int timer, uint32_t reload_val)
{
mcpwm->timer[timer].sync.timer_phase = reload_val;
}
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_SELECT_SYNC0, 4);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_SELECT_SYNC1, 5);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_SELECT_SYNC2, 6);
/**
* Set the sync signal source for a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param timer The timer to set, 0-2.
* @param sync_sig The synchronization signal to use.
*/
static inline void mcpwm_ll_sync_set_input(mcpwm_dev_t *mcpwm, int timer, mcpwm_sync_signal_t sync_sig)
{
if (timer == 0) {
mcpwm->timer_synci_cfg.t0_in_sel = sync_sig;
} else if (timer == 1) {
mcpwm->timer_synci_cfg.t1_in_sel = sync_sig;
} else { //MCPWM_TIMER_2
mcpwm->timer_synci_cfg.t2_in_sel = sync_sig;
}
}
/********************* Comparator *******************/
/**
* Select a timer for the specified operator to use.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to choose timer, 0-2.
* @param timer The timer to use, 0-2.
*/
static inline void mcpwm_ll_operator_select_timer(mcpwm_dev_t *mcpwm, int op, int timer)
{
if (op == 0) {
mcpwm->timer_sel.operator0_sel = timer;
} else if (op == 1) {
mcpwm->timer_sel.operator1_sel = timer;
} else {
mcpwm->timer_sel.operator2_sel = timer;
}
}
/**
* Set the update method of the compare value of a timer
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op Operator to set, 0-2.
*/
static inline void mcpwm_ll_operator_set_compare_upmethod(mcpwm_dev_t *mcpwm, int op)
{
mcpwm->channel[op].cmpr_cfg.a_upmethod = BIT(0);
mcpwm->channel[op].cmpr_cfg.b_upmethod = BIT(0);
}
/**
* Get one of the compare value of a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to get, 0-2.
* @param cmp_n Comparer id to get, 0-1.
* @return The set compare value.
*/
static inline uint32_t mcpwm_ll_operator_get_compare(mcpwm_dev_t *mcpwm, int op, int cmp_n)
{
return (mcpwm->channel[op].cmpr_value[cmp_n].cmpr_val);
}
/**
* Set one of the compare value of a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param cmp_n The comparer to set value, 0-1.
* @param compare The compare value, 0-65535.
*/
static inline void mcpwm_ll_operator_set_compare(mcpwm_dev_t *mcpwm, int op, int cmp_n, uint32_t compare)
{
mcpwm->channel[op].cmpr_value[cmp_n].cmpr_val = compare;
}
/********************* Generator *******************/
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_ACTION_NO_CHANGE, 0);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_ACTION_FORCE_LOW, 1);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_ACTION_FORCE_HIGH, 2);
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_ACTION_TOGGLE, 3);
/**
* Set the action will be taken by a operator when its timer counts to zero.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set action, 0-2.
* @param gen One generator of the operator to take the action, 0-1.
* @param action Action to take.
*/
static inline void mcpwm_ll_gen_set_zero_action(mcpwm_dev_t *mcpwm, int op, int gen, mcpwm_output_action_t action)
{
mcpwm->channel[op].generator[gen].utez = action;
mcpwm->channel[op].generator[gen].dtez = action;
}
/**
* Set the action will be taken by a operator when its timer counts to the period value.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set action, 0-2.
* @param gen One generator of the operator to take the action, 0-1.
* @param action Action to take.
*/
static inline void mcpwm_ll_gen_set_period_action(mcpwm_dev_t *mcpwm, int op, int gen, mcpwm_output_action_t action)
{
mcpwm->channel[op].generator[gen].utep = action;
mcpwm->channel[op].generator[gen].dtep = action;
}
/**
* Set the action will be taken by a operator when its timer counts to the compare value.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set action, 0-2.
* @param gen One generator of the operator to take the action, 0-1.
* @param cmp_n The comparer to use.
* @param up_action The action to take when the counter is counting up.
* @param down_action The action to take when the counter is counting down.
*/
static inline void mcpwm_ll_gen_set_cmp_action(mcpwm_dev_t *mcpwm, int op, int gen,
int cmp_n, mcpwm_output_action_t up_action, mcpwm_output_action_t down_action)
{
if (cmp_n == 0) {
mcpwm->channel[op].generator[gen].utea = up_action;
mcpwm->channel[op].generator[gen].dtea = down_action;
} else {
mcpwm->channel[op].generator[gen].uteb = up_action;
mcpwm->channel[op].generator[gen].dteb = down_action;
}
}
/********************* Fault *******************/
/**
* Enable the fault detection feature for an input signal.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param fault_sig One of the signals to select, 0-2.
* @param level The active level of the fault-detection signal.
*/
static inline void mcpwm_ll_fault_enable(mcpwm_dev_t *mcpwm, int fault_sig, bool level)
{
if (fault_sig == 0) {
mcpwm->fault_detect.f0_en = 1;
mcpwm->fault_detect.f0_pole = level;
} else if (fault_sig == 1) {
mcpwm->fault_detect.f1_en = 1;
mcpwm->fault_detect.f1_pole = level;
} else { //MCPWM_SELECT_F2
mcpwm->fault_detect.f2_en = 1;
mcpwm->fault_detect.f2_pole = level;
}
}
/**
* Disable the fault detection of an input signal.
* @param mcpwm Address of the MCPWM peripheral registers.
* @param fault_sig The signal to disable, 0-2.
*/
static inline void mcpwm_ll_fault_disable(mcpwm_dev_t *mcpwm, int fault_sig)
{
if (fault_sig == 0) {
mcpwm->fault_detect.f0_en = 0;
} else if (fault_sig == 1) {
mcpwm->fault_detect.f1_en = 0;
} else { //MCPWM_SELECT_F2
mcpwm->fault_detect.f2_en = 0;
}
}
/**
* Clear the oneshot fault status of an operator.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to clear, 0-2.
*/
static inline void mcpwm_ll_fault_clear_ost(mcpwm_dev_t *mcpwm, int op)
{
mcpwm->channel[op].tz_cfg1.clr_ost = 1;
mcpwm->channel[op].tz_cfg1.clr_ost = 0;
}
/**
* Use the oneshot mode to handle the fault when it occurs
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to handle the fault signal, 0-2.
* @param signal The fault signal to set, 0-2.
* @param enable true to enable oneshot, otherwise false.
*/
static inline void mcpwm_ll_fault_oneshot_enable_signal(mcpwm_dev_t *mcpwm, int op, int signal, bool enable)
{
if (signal == 0) {
mcpwm->channel[op].tz_cfg0.f0_ost = enable;
} else if (signal == 1) {
mcpwm->channel[op].tz_cfg0.f1_ost = enable;
} else { //MCPWM_SELECT_F2
mcpwm->channel[op].tz_cfg0.f2_ost = enable;
}
}
/**
* @brief Get the oneshot enabled status of the operator
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to check, 0-2.
* @param signal The fault signal to get, 0-2.
*/
static inline bool mcpwm_ll_fault_oneshot_signal_enabled(mcpwm_dev_t *mcpwm, int op, int signal)
{
if (signal == 0) {
return mcpwm->channel[op].tz_cfg0.f0_ost;
} else if (signal == 1) {
return mcpwm->channel[op].tz_cfg0.f1_ost;
} else { //MCPWM_SELECT_F2
return mcpwm->channel[op].tz_cfg0.f2_ost;
}
}
/**
* Use the CBC (cycle-by-cycle) mode to handle the fault when it occurs.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to handle the fault signal, 0-2.
* @param signal The fault signal to set, 0-2.
* @param enable true to enable cbc mode, otherwise false.
*/
static inline void mcpwm_ll_fault_cbc_enable_signal(mcpwm_dev_t *mcpwm, int op, int signal, bool enable)
{
if (signal == 0) {
mcpwm->channel[op].tz_cfg0.f0_cbc = enable;
} else if (signal == 1) {
mcpwm->channel[op].tz_cfg0.f1_cbc = enable;
} else { //MCPWM_SELECT_F2
mcpwm->channel[op].tz_cfg0.f2_cbc = enable;
}
}
/**
* Set the action that will be taken when the fault is handled by oneshot.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to handle the fault signal, 0-2.
* @param gen The generator to take the action, 0-1.
* @param up_action Action to take when fault happens when counting up.
* @param down_action Action to take when fault happens when counting down.
*/
static inline void mcpwm_ll_fault_set_oneshot_action(mcpwm_dev_t *mcpwm, int op, int gen,
mcpwm_output_action_t up_action, mcpwm_output_action_t down_action)
{
if (gen == 0) {
mcpwm->channel[op].tz_cfg0.a_ost_u = up_action;
mcpwm->channel[op].tz_cfg0.a_ost_d = down_action;
} else {
mcpwm->channel[op].tz_cfg0.b_ost_u = up_action;
mcpwm->channel[op].tz_cfg0.b_ost_d = down_action;
}
}
/**
* Set the action that will be taken when the fault is handled cycle by cycle.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to handle the fault signal, 0-2.
* @param gen The generator to take the action, 0-1.
* @param up_action Action to take when fault happens when counting up.
* @param down_action Action to take when fault happens when counting down.
*/
static inline void mcpwm_ll_fault_set_cyc_action(mcpwm_dev_t *mcpwm, int op, int gen,
mcpwm_output_action_t up_action, mcpwm_output_action_t down_action)
{
mcpwm->channel[op].tz_cfg1.cbcpulse = BIT(0); //immediately
if (gen == 0) {
mcpwm->channel[op].tz_cfg0.a_cbc_u = up_action;
mcpwm->channel[op].tz_cfg0.a_cbc_d = down_action;
} else {
mcpwm->channel[op].tz_cfg0.b_cbc_u = up_action;
mcpwm->channel[op].tz_cfg0.b_cbc_d = down_action;
}
}
/********************* Dead Zone (deadtime) *******************/
/**
* Initialize the dead zone feature.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to initialize, 0-2.
*/
static inline void mcpwm_ll_deadtime_init(mcpwm_dev_t *mcpwm, int op)
{
mcpwm->channel[op].db_cfg.fed_upmethod = BIT(0);
mcpwm->channel[op].db_cfg.red_upmethod = BIT(0);
mcpwm->channel[op].db_cfg.clk_sel = 0;
}
/**
* Set the output dead zone mode applying to the outputs of a timer.
*
* If the desired internal connection is not provided, you can write your own inside this function.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param mode Dead zone mode to use.
*/
static inline void mcpwm_ll_set_deadtime_mode(mcpwm_dev_t *mcpwm,
int op, mcpwm_deadtime_type_t mode)
{
#define MCPWM_LL_DEADTIME_REG_MASK (MCPWM_DT0_DEB_MODE_M | MCPWM_DT0_A_OUTSWAP_M | MCPWM_DT0_B_OUTSWAP_M | \
MCPWM_DT0_RED_INSEL_M | MCPWM_DT0_FED_INSEL_M | MCPWM_DT0_RED_OUTINVERT_M | MCPWM_DT0_FED_OUTINVERT_M | \
MCPWM_DT0_A_OUTBYPASS_M | MCPWM_DT0_B_OUTBYPASS_M)
static uint32_t deadtime_mode_settings[MCPWM_DEADTIME_TYPE_MAX] = {
[MCPWM_BYPASS_RED] = 0b010010000 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_BYPASS_FED] = 0b100000000 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_ACTIVE_HIGH_MODE] = 0b000010000 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_ACTIVE_LOW_MODE] = 0b001110000 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_ACTIVE_HIGH_COMPLIMENT_MODE] = 0b001010000 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_ACTIVE_LOW_COMPLIMENT_MODE] = 0b000101000 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_ACTIVE_RED_FED_FROM_PWMXA] = 0b000000011 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_ACTIVE_RED_FED_FROM_PWMXB] = 0b000001011 << MCPWM_DT0_DEB_MODE_S,
[MCPWM_DEADTIME_BYPASS] = 0b110000000 << MCPWM_DT0_DEB_MODE_S,
};
mcpwm->channel[op].db_cfg.val =
(mcpwm->channel[op].db_cfg.val & (~MCPWM_LL_DEADTIME_REG_MASK)) | deadtime_mode_settings[mode];
#undef MCPWM_LL_DEADTIME_REG_MASK
}
/**
* Set the delay of the falling edge on the output.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param fed Falling delay, by PWM main clock.
*/
static inline void mcpwm_ll_deadtime_set_falling_delay(mcpwm_dev_t *mcpwm, int op, uint32_t fed)
{
mcpwm->channel[op].db_fed_cfg.fed = fed;
}
/**
* Set the delay of the rising edge on the output.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param fed Rising delay, by PWM main clock.
*/
static inline void mcpwm_ll_deadtime_set_rising_delay(mcpwm_dev_t *mcpwm, int op, uint32_t red)
{
mcpwm->channel[op].db_red_cfg.red = red;
}
/**
* Disable (bypass) the dead zone feature.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
*/
static inline void mcpwm_ll_deadtime_bypass(mcpwm_dev_t *mcpwm, int op)
{
mcpwm_ll_set_deadtime_mode(mcpwm, op, MCPWM_DEADTIME_BYPASS);
}
/********************* Carrier *******************/
/**
* Initialize the carrier feature.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
*/
static inline void mcpwm_ll_carrier_init(mcpwm_dev_t *mcpwm, int op)
{
mcpwm->channel[op].carrier_cfg.in_invert = 0;
}
/**
* Enable the carrier feature for a timer.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param enable true to enable, otherwise false.
*/
static inline void mcpwm_ll_carrier_enable(mcpwm_dev_t *mcpwm, int op, bool enable)
{
mcpwm->channel[op].carrier_cfg.en = enable;
}
/**
* Set the prescale of the carrier timer.
*
* The carrier period will be Frequency of PWM main clock/(carrier_period+1).
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param carrier_period The prescale of the carrier clock, 0-15.
*/
static inline void mcpwm_ll_carrier_set_prescale(mcpwm_dev_t *mcpwm, int op, uint8_t carrier_period)
{
mcpwm->channel[op].carrier_cfg.prescale = carrier_period;
}
/**
* Set the duty rate of the carrier.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param carrier_duty Duty rate will be (carrier_duty/8)*100%. 0-7.
*/
static inline void mcpwm_ll_carrier_set_duty(mcpwm_dev_t *mcpwm, int op, uint8_t carrier_duty)
{
mcpwm->channel[op].carrier_cfg.duty = carrier_duty;
}
/**
* Invert output of the carrier.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param invert true to invert, otherwise false.
*/
static inline void mcpwm_ll_carrier_out_invert(mcpwm_dev_t *mcpwm, int op, bool invert)
{
mcpwm->channel[op].carrier_cfg.out_invert = invert;
}
/**
* Set the oneshot pulse width of the carrier.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param op The operator to set, 0-2.
* @param pulse_width The width of the oneshot pulse, by carrier period. 0 to disable the oneshot pulse.
*/
static inline void mcpwm_ll_carrier_set_oneshot_width(mcpwm_dev_t *mcpwm, int op, uint8_t pulse_width)
{
mcpwm->channel[op].carrier_cfg.oshtwth = pulse_width;
}
/********************* Capture *******************/
/**
* Enable the capture feature for a signal
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param cap_sig Signal to enable, 0-2.
* @param enable true to enable, otherwise false.
*/
static inline void mcpwm_ll_capture_enable(mcpwm_dev_t *mcpwm, int cap_sig, int enable)
{
if (enable) {
mcpwm->cap_timer_cfg.timer_en = 1;
mcpwm->cap_cfg_ch[cap_sig].en = 1;
} else {
mcpwm->cap_cfg_ch[cap_sig].en = 0;
}
}
/**
* Get the captured value.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param cap_sig Of which signal to get the captured value.
* @return The captured value
*/
static inline uint32_t mcpwm_ll_get_capture_val(mcpwm_dev_t *mcpwm, int cap_sig)
{
return mcpwm->cap_val_ch[cap_sig];
}
/**
* Get the set capture edge.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param cap_sig Which signal the edge capture is applied.
* @return Capture signal edge: 1 - positive edge, 2 - negtive edge
*/
static inline mcpwm_capture_on_edge_t mcpwm_ll_get_captured_edge(mcpwm_dev_t *mcpwm, int cap_sig)
{
bool edge;
if (cap_sig == 0) {
edge = mcpwm->cap_status.cap0_edge;
} else if (cap_sig == 1) {
edge = mcpwm->cap_status.cap0_edge;
} else { //2
edge = mcpwm->cap_status.cap0_edge;
}
return (edge? MCPWM_NEG_EDGE: MCPWM_POS_EDGE);
}
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_NEG_EDGE, BIT(0));
STATIC_HAL_REG_CHECK(MCPWM, MCPWM_POS_EDGE, BIT(1));
/**
* Select the edge to capture.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param cap_sig The signal to capture, 0-2.
* @param cap_edge The edge to capture, bitwise.
*/
static inline void mcpwm_ll_capture_select_edge(mcpwm_dev_t *mcpwm, int cap_sig,
mcpwm_capture_on_edge_t cap_edge)
{
mcpwm->cap_cfg_ch[cap_sig].mode = cap_edge;
}
/**
* Set the prescale of the input signal to capture.
*
* @param mcpwm Address of the MCPWM peripheral registers.
* @param cap_sig The prescaled signal to capture, 0-2.
* @param prescale Prescal value, 0 to disable.
*/
static inline void mcpwm_ll_capture_set_prescale(mcpwm_dev_t *mcpwm, int cap_sig, uint32_t prescale)
{
mcpwm->cap_cfg_ch[cap_sig].prescale = prescale;
}
/**
* Utility function, get the `mcpwm_intr_t` interrupt enum of a specific capture signal.
*
* @param bit x for CAPx.
* @return the corresponding `mcpwm_intr_t`.
*/
static inline mcpwm_intr_t mcpwm_ll_get_cap_intr_def(int bit)
{
return BIT(bit+MCPWM_CAP0_INT_RAW_S);
}