Michael (XIAO Xufeng) 647dea9395 soc: combine xxx_caps.h into one soc_caps.h
During HAL layer refactoring and new chip bringup, we have several
caps.h for each part, to reduce the conflicts to minimum. But this is
The capabilities headers will be relataive stable once completely
written (maybe after the featues are supported by drivers).

Now ESP32 and ESP32-S2 drivers are relative stable, making it a good
time to combine all these caps.h into one soc_caps.h

This cleanup also move HAL config and pin config into separated files,
to make the responsibilities of these headers more clear. This is
helpful for the stabilities of soc_caps.h because we want to make it
public some day.
2020-10-17 16:10:15 +08:00

735 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 hal/include/hal/readme.md
******************************************************************************/
// The LL layer for ESP32 MCPWM register operations
#pragma once
#include "soc/soc_caps.h"
#include <soc/mcpwm_periph.h>
#include "soc/mcpwm_periph.h"
#include "hal/mcpwm_types.h"
#include "hal/hal_defs.h"
#include "esp_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/// 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;
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;
}
/********************* 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);
}
#ifdef __cplusplus
}
#endif