#ifndef __LKS32MC09X_MCPWM_H__
#define __LKS32MC09X_MCPWM_H__
#include "lks32mc09x_reg.h"

typedef struct
{
    // 基本配置项
    uint16_t EN;      // 模块使能，1使能，0不使能，不使能时MCPWM模块会被复位，下面的配置项无意义
    uint32_t COUNT;   // 计数器配置，参考MCPWM_COUNT_x，例如MCPWM_COUNT_START
    uint16_t CLK_DIV; // 时钟分频配置，参考MCPWM_CLK_DIV_x，例如MCPWM_CLK_DIV_1
    uint16_t TH;      // 计数器门限值（PWM周期），0-32767，设置为0后cnt恒为0，无意义
    uint16_t TR;      // 自动更新时刻，参考MCPWM_TR_x，例如MCPWM_TR_T0
    int16_t TMR0;     // PWM触发ADC事件0时间点，-32768到32767
    int16_t TMR1;     // PWM触发ADC事件1时间点，-32768到32767
    int16_t TMR2;     // PWM触发ADC事件2时间点，-32768到32767
    int16_t TMR3;     // PWM触发ADC事件3时间点，-32768到32767
    uint16_t DTHP;    // 上管死区时间设置，0-1023
    uint16_t DTHN;    // 下管死区时间设置，0-1023
    uint16_t FLT_DIV; // fail信号滤波时钟分频，取值范围 0-255 对应1分频到256分频
    uint16_t IO0;     // 通道0输出IO配置，参考MCPWM_IO_x，例如MCPWM_IO_HH_PWM
    uint16_t IO1;     // 通道1输出IO配置，参考MCPWM_IO_x，例如MCPWM_IO_HH_PWM
    uint16_t IO2;     // 通道2输出IO配置，参考MCPWM_IO_x，例如MCPWM_IO_HH_PWM
    uint16_t IO3;     // 通道3输出IO配置，参考MCPWM_IO_x，例如MCPWM_IO_HH_PWM
    uint32_t AUEN;    // 自动更新使能，参考MCPWM_AUEN_x，例如MCPWM_AUEN_ALL
    uint32_t IE;      // 常规中断，参考MCPWM_IE_x，例如MCPWM_IF_T0
    uint32_t EIE;     // 错误中断 fail信号产生的中断，参考MCPWM_EIE_x，例如MCPWM_EIE_FAIL0
    uint32_t RE;      // DMA请求信号配置
    uint32_t FAIL_IO; // fail和关闭输出后的IO状态配置，参考MCPWM_FAIL_IO_x，例如MCPWM_FAIL_IO_HIGH
    uint32_t FAIL0;   // FAIL0信号来源配置，参考MCPWM_FAIL0_x，例如MCPWM_FAIL0_x
    uint32_t FAIL1;   // FAIL1信号来源配置，参考MCPWM_FAIL1_x，例如MCPWM_FAIL1_x
} MCPWM_InitTypeDef;

// 常规中断配置
#define MCPWM_IF_UP   BIT14 // 时基 0 更新事件 MCPWM0_TH0/MCPWM0_TH00~MCPWM0_TH21/MCPWM0_TMR 等寄存器更新到 MCPWM 实际运行系统的中断事件。
#define MCPWM_IF_TMR3 BIT13 // MCPWM0_CNT0 等于 MCPWM0_TMR3 中断事件。
#define MCPWM_IF_TMR2 BIT12 // MCPWM0_CNT0 等于 MCPWM0_TMR2 中断事件。
#define MCPWM_IF_TMR1 BIT11 // MCPWM0_CNT0 等于 MCPWM0_TMR1 中断事件。
#define MCPWM_IF_TMR0 BIT10 // MCPWM0_CNT0 等于 MCPWM0_TMR0 中断事件。
#define MCPWM_IF_TH21 BIT7  // MCPWM0_CNT0 等于 MCPWM0_TH21 中断事件。
#define MCPWM_IF_TH20 BIT6  // MCPWM0_CNT0 等于 MCPWM0_TH20 中断事件。
#define MCPWM_IF_TH11 BIT5  // MCPWM0_CNT0 等于 MCPWM0_TH11 中断事件。
#define MCPWM_IF_TH10 BIT4  // MCPWM0_CNT0 等于 MCPWM0_TH10 中断事件。
#define MCPWM_IF_TH01 BIT3  // MCPWM0_CNT0 等于 MCPWM0_TH01 中断事件。
#define MCPWM_IF_TH00 BIT2  // MCPWM0_CNT0 等于 MCPWM0_TH00 中断事件。
#define MCPWM_IF_T1   BIT1  // t1 事件，MCPWM0_CNT0 等于 0 中断事件。
#define MCPWM_IF_T0   BIT0  // t0 事件，MCPWM0_CNT0 等于 MCPWM0_TH 中断事件。
// IE和IF寄存器对应位一致
#define MCPWM_IE_UP   MCPWM_IF_UP
#define MCPWM_IE_TMR3 MCPWM_IF_TMR3
#define MCPWM_IE_TMR2 MCPWM_IF_TMR2
#define MCPWM_IE_TMR1 MCPWM_IF_TMR1
#define MCPWM_IE_TMR0 MCPWM_IF_TMR0
#define MCPWM_IE_TH21 MCPWM_IF_TH21
#define MCPWM_IE_TH20 MCPWM_IF_TH20
#define MCPWM_IE_TH11 MCPWM_IF_TH11
#define MCPWM_IE_TH10 MCPWM_IF_TH10
#define MCPWM_IE_TH01 MCPWM_IF_TH01
#define MCPWM_IE_TH00 MCPWM_IF_TH00
#define MCPWM_IE_T1   MCPWM_IF_T1
#define MCPWM_IE_T0   MCPWM_IF_T0
// 故障中断配置
#define MCPWM_EIF_FAIL0    BIT4 // FAIL1 中断源事件。
#define MCPWM_EIF_FAIL1    BIT5 // FAIL0 中断源事件。
#define MCPWM_EIE_FAIL0    MCPWM_EIF_FAIL0
#define MCPWM_EIE_FAIL1    MCPWM_EIF_FAIL1

#define MCPWM_AUEN_IO3     BIT28 // MCPWM0_IO3  自动加载使能
#define MCPWM_AUEN_TMR3    BIT25 // MCPWM0_TMR3 自动加载使能
#define MCPWM_AUEN_TMR2    BIT24 // MCPWM0_TMR2 自动加载使能
#define MCPWM_AUEN_TH31    BIT17 // MCPWM0_TH31 自动加载使能
#define MCPWM_AUEN_TH30    BIT16 // MCPWM0_TH30 自动加载使能
#define MCPWM_AUEN_IO012   BIT12 // MCPWM0_IO012 自动加载使能
#define MCPWM_AUEN_CNT0    BIT11 // MCPWM0_CNT0 自动加载使能
#define MCPWM_AUEN_TH0     BIT10 // MCPWM0_TH0  自动加载使能
#define MCPWM_AUEN_TMR1    BIT9  // MCPWM0_TMR1 自动加载使能
#define MCPWM_AUEN_TMR0    BIT8  // MCPWM0_TMR0 自动加载使能
#define MCPWM_AUEN_TH21    BIT5  // MCPWM0_TH21 自动加载使能
#define MCPWM_AUEN_TH20    BIT4  // MCPWM0_TH20 自动加载使能
#define MCPWM_AUEN_TH11    BIT3  // MCPWM0_TH11 自动加载使能
#define MCPWM_AUEN_TH10    BIT2  // MCPWM0_TH10 自动加载使能
#define MCPWM_AUEN_TH01    BIT1  // MCPWM0_TH01 自动加载使能
#define MCPWM_AUEN_TH00    BIT0  // MCPWM0_TH00 自动加载使能

#define MCPWM_AUEN_IO      (MCPWM_AUEN_IO012 | MCPWM_AUEN_IO3) // MCPWM0_IO  自动加载使能

#define MCPWM_AUEN_ALL     (MCPWM_AUEN_IO3 | MCPWM_AUEN_TMR3 | MCPWM_AUEN_TMR2 | MCPWM_AUEN_TH31 | MCPWM_AUEN_TH30 | MCPWM_AUEN_IO012 | MCPWM_AUEN_CNT0 | MCPWM_AUEN_TH0 | MCPWM_AUEN_TMR1 | MCPWM_AUEN_TMR0 | MCPWM_AUEN_TH21 | MCPWM_AUEN_TH20 | MCPWM_AUEN_TH11 | MCPWM_AUEN_TH10 | MCPWM_AUEN_TH01 | MCPWM_AUEN_TH00) // 打开所有自动加载使能

#define MCPWM_AUEN_DEFAULT (MCPWM_AUEN_ALL ^ MCPWM_AUEN_CNT0) // 通常不会打开cnt的自动更新使能

// mcpwmIO状态配置位定义
#define MCPWM_IO_WM     BIT7 // CH0 工作模式选择。1:边沿模式；0:互补模式
#define MCPWM_IO_PN_SW  BIT6 // CH0 的 P 和 N 通道输出互换选择。即 P 通道信号最后从 N 通道输出，N 通道的信号最后从 P 通道输出。1:互换；0:不互换。
#define MCPWM_IO_SCTRLP BIT5 // 当 CH0_PS =1 时，输出到 CH0 P 通道的值。1上管打开 0上管关闭
#define MCPWM_IO_SCTRLN BIT4 // 当 CH0_NS =1 时，输出到 CH0 N 通道的值。1下管打开 0下管关闭
#define MCPWM_IO_PS     BIT3 // P 来源。1:来自 CH0_SCTRLP；0:MCPWM 实际运行系统中计数器产生。
#define MCPWM_IO_NS     BIT2 // N 来源。1:来自 CH0_SCTRLN；0:MCPWM 实际运行系统中计数器产生。
#define MCPWM_IO_PP     BIT1 // P 极性选择。1 上管低有效 0 上管高有效
#define MCPWM_IO_NP     BIT0 // N 极性选择。1 下管低有效 0 下管高有效
// 互补模式下io配置项
#define MCPWM_IO_DISABLE  0                                             // 不使用该通道(默认配置：上管高有效，下管高有效，正常输出PWM)
#define MCPWM_IO_HH_PWM   0                                             // 上管高有效，下管高有效，正常输出PWM
#define MCPWM_IO_HH_LOW   (MCPWM_IO_SCTRLN | MCPWM_IO_PS | MCPWM_IO_NS) // 上管高有效，下管高有效，下管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_HH_HIGH  (MCPWM_IO_SCTRLP | MCPWM_IO_PS | MCPWM_IO_NS) // 上管高有效，下管高有效，上管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_HH_HPWM  (MCPWM_IO_NS)                                 // 上管高有效，下管高有效，上管斩波
#define MCPWM_IO_HH_LPWM  (MCPWM_IO_PS)                                 // 上管高有效，下管高有效，下管斩波
#define MCPWM_IO_HH_OFF   (MCPWM_IO_NS | MCPWM_IO_PS)                   // 上管高有效，下管高有效，上下管全关，和MOE不同，通过IO可以关闭任意一路pwm

#define MCPWM_IO_HHS_PWM  (MCPWM_IO_HH_PWM | MCPWM_IO_PN_SW)  // 上管高有效，下管高有效，通道交换打开，正常输出PWM
#define MCPWM_IO_HHS_LOW  (MCPWM_IO_HH_LOW | MCPWM_IO_PN_SW)  // 上管高有效，下管高有效，通道交换打开，下管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_HHS_HIGH (MCPWM_IO_HH_HIGH | MCPWM_IO_PN_SW) // 上管高有效，下管高有效，通道交换打开，上管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_HHS_HPWM (MCPWM_IO_HH_HPWM | MCPWM_IO_PN_SW) // 上管高有效，下管高有效，通道交换打开，上管斩波
#define MCPWM_IO_HHS_LPWM (MCPWM_IO_HH_LPWM | MCPWM_IO_PN_SW) // 上管高有效，下管高有效，通道交换打开，下管斩波
#define MCPWM_IO_HHS_OFF  (MCPWM_IO_HH_OFF | MCPWM_IO_PN_SW)  // 上管高有效，下管高有效，通道交换打开，上下管全关，和MOE不同，通过IO可以关闭任意一路pwm

#define MCPWM_IO_HL_PWM   (MCPWM_IO_NP)                                               // 上管高有效，下管低有效，正常输出PWM
#define MCPWM_IO_HL_LOW   (MCPWM_IO_NP | MCPWM_IO_SCTRLN | MCPWM_IO_PS | MCPWM_IO_NS) // 上管高有效，下管低有效，下管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_HL_HIGH  (MCPWM_IO_NP | MCPWM_IO_SCTRLP | MCPWM_IO_PS | MCPWM_IO_NS) // 上管高有效，下管低有效，上管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_HL_HPWM  (MCPWM_IO_NP | MCPWM_IO_NS)                                 // 上管高有效，下管低有效，上管斩波
#define MCPWM_IO_HL_LPWM  (MCPWM_IO_NP | MCPWM_IO_PS)                                 // 上管高有效，下管低有效，下管斩波
#define MCPWM_IO_HL_OFF   (MCPWM_IO_NP | MCPWM_IO_NS | MCPWM_IO_PS)                   // 上管高有效，下管低有效，上下管全关，和MOE不同，通过IO可以关闭任意一路pwm

#define MCPWM_IO_HLS_PWM  (MCPWM_IO_HL_PWM | MCPWM_IO_PN_SW)  // 上管高有效，下管低有效，通道交换打开，正常输出PWM
#define MCPWM_IO_HLS_LOW  (MCPWM_IO_HL_LOW | MCPWM_IO_PN_SW)  // 上管高有效，下管低有效，通道交换打开，下管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_HLS_HIGH (MCPWM_IO_HL_HIGH | MCPWM_IO_PN_SW) // 上管高有效，下管低有效，通道交换打开，上管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_HLS_HPWM (MCPWM_IO_HL_HPWM | MCPWM_IO_PN_SW) // 上管高有效，下管低有效，通道交换打开，上管斩波
#define MCPWM_IO_HLS_LPWM (MCPWM_IO_HL_LPWM | MCPWM_IO_PN_SW) // 上管高有效，下管低有效，通道交换打开，下管斩波
#define MCPWM_IO_HLS_OFF  (MCPWM_IO_HL_OFF | MCPWM_IO_PN_SW)  // 上管高有效，下管低有效，通道交换打开，上下管全关，和MOE不同，通过IO可以关闭任意一路pwm

#define MCPWM_IO_LH_PWM   (MCPWM_IO_PP)                                               // 上管低有效，下管高有效，正常输出PWM
#define MCPWM_IO_LH_LOW   (MCPWM_IO_PP | MCPWM_IO_SCTRLN | MCPWM_IO_PS | MCPWM_IO_NS) // 上管低有效，下管高有效，下管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_LH_HIGH  (MCPWM_IO_PP | MCPWM_IO_SCTRLP | MCPWM_IO_PS | MCPWM_IO_NS) // 上管低有效，下管高有效，上管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_LH_HPWM  (MCPWM_IO_PP | MCPWM_IO_NS)                                 // 上管低有效，下管高有效，上管斩波
#define MCPWM_IO_LH_LPWM  (MCPWM_IO_PP | MCPWM_IO_PS)                                 // 上管低有效，下管高有效，下管斩波
#define MCPWM_IO_LH_OFF   (MCPWM_IO_PP | MCPWM_IO_NS | MCPWM_IO_PS)                   // 上管低有效，下管高有效，上下管全关，和MOE不同，通过IO可以关闭任意一路pwm

#define MCPWM_IO_LHS_PWM  (MCPWM_IO_LH_PWM | MCPWM_IO_PN_SW)  // 上管低有效，下管高有效，通道交换打开，正常输出PWM
#define MCPWM_IO_LHS_LOW  (MCPWM_IO_LH_LOW | MCPWM_IO_PN_SW)  // 上管低有效，下管高有效，通道交换打开，下管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_LHS_HIGH (MCPWM_IO_LH_HIGH | MCPWM_IO_PN_SW) // 上管低有效，下管高有效，通道交换打开，上管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_LHS_HPWM (MCPWM_IO_LH_HPWM | MCPWM_IO_PN_SW) // 上管低有效，下管高有效，通道交换打开，上管斩波
#define MCPWM_IO_LHS_LPWM (MCPWM_IO_LH_LPWM | MCPWM_IO_PN_SW) // 上管低有效，下管高有效，通道交换打开，下管斩波
#define MCPWM_IO_LHS_OFF  (MCPWM_IO_LH_OFF | MCPWM_IO_PN_SW)  // 上管低有效，下管高有效，通道交换打开，上下管全关，和MOE不同，通过IO可以关闭任意一路pwm

#define MCPWM_IO_LL_PWM   (MCPWM_IO_PP | MCPWM_IO_NP)                                               // 上管低有效，下管低有效，正常输出PWM
#define MCPWM_IO_LL_LOW   (MCPWM_IO_PP | MCPWM_IO_NP | MCPWM_IO_SCTRLN | MCPWM_IO_PS | MCPWM_IO_NS) // 上管低有效，下管低有效，下管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_LL_HIGH  (MCPWM_IO_PP | MCPWM_IO_NP | MCPWM_IO_SCTRLP | MCPWM_IO_PS | MCPWM_IO_NS) // 上管低有效，下管低有效，上管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_LL_HPWM  (MCPWM_IO_PP | MCPWM_IO_NP | MCPWM_IO_NS)                                 // 上管低有效，下管低有效，上管斩波
#define MCPWM_IO_LL_LPWM  (MCPWM_IO_PP | MCPWM_IO_NP | MCPWM_IO_PS)                                 // 上管低有效，下管低有效，下管斩波
#define MCPWM_IO_LL_OFF   (MCPWM_IO_PP | MCPWM_IO_NP | MCPWM_IO_NS | MCPWM_IO_PS)                   // 上管低有效，下管低有效，上下管全关，和MOE不同，通过IO可以关闭任意一路pwm

#define MCPWM_IO_LLS_PWM  (MCPWM_IO_LL_PWM | MCPWM_IO_PN_SW)  // 上管低有效，下管低有效，通道交换打开，正常输出PWM
#define MCPWM_IO_LLS_LOW  (MCPWM_IO_LL_LOW | MCPWM_IO_PN_SW)  // 上管低有效，下管低有效，通道交换打开，下管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_LLS_HIGH (MCPWM_IO_LL_HIGH | MCPWM_IO_PN_SW) // 上管低有效，下管低有效，通道交换打开，上管恒开 此时pwm配置无效，但仍然会正常计数&触发中断
#define MCPWM_IO_LLS_HPWM (MCPWM_IO_LL_HPWM | MCPWM_IO_PN_SW) // 上管低有效，下管低有效，通道交换打开，上管斩波
#define MCPWM_IO_LLS_LPWM (MCPWM_IO_LL_LPWM | MCPWM_IO_PN_SW) // 上管低有效，下管低有效，通道交换打开，下管斩波
#define MCPWM_IO_LLS_OFF  (MCPWM_IO_LL_OFF | MCPWM_IO_PN_SW)  // 上管低有效，下管低有效，通道交换打开，上下管全关，和MOE不同，通过IO可以关闭任意一路pwm

// 计数器配置
#define MCPWM_COUNT_OFF             0     // 计数器停止计数
#define MCPWM_COUNT_START           BIT31 // 计数器立即开始计数
#define MCPWM_COUNT_EVT_TIMER0_CMP0 BIT0  // timer0的通道0事件触发MCPWM开始计数
#define MCPWM_COUNT_EVT_TIMER0_CMP1 BIT1  // timer0的通道1事件触发MCPWM开始计数
#define MCPWM_COUNT_EVT_TIMER1_CMP0 BIT2  // timer1的通道0事件触发MCPWM开始计数
#define MCPWM_COUNT_EVT_TIMER1_CMP1 BIT3  // timer1的通道1事件触发MCPWM开始计数
#define MCPWM_COUNT_EVT_TIMER2_CMP0 BIT4  // timer2的通道0事件触发MCPWM开始计数
#define MCPWM_COUNT_EVT_TIMER2_CMP1 BIT5  // timer2的通道1事件触发MCPWM开始计数

#define MCPWM_CLK_DIV_1             0 // 时钟1分频
#define MCPWM_CLK_DIV_2             1 // 时钟2分频
#define MCPWM_CLK_DIV_4             2 // 时钟4分频
#define MCPWM_CLK_DIV_8             3 // 时钟8分频
#define MCPWM_CLK_DIV_16            4 // 时钟16分频
#define MCPWM_CLK_DIV_32            5 // 时钟32分频
#define MCPWM_CLK_DIV_64            6 // 时钟64分频
#define MCPWM_CLK_DIV_128           7 // 时钟128分频
// 自动更新配置，通常配置为溢出时刻进行更新
#define MCPWM_TR_T0 BIT4 // cnt溢出时刻触发自动更新（CNT起点）
#define MCPWM_TR_T1 BIT5 // cnt过零时刻触发自动更新

// 注意，这里的fail信号配置会参考IO里配置的通道交换和极性配置进行进一步交换
#define MCPWM_FAIL_IO_HIGH 0xaa // 触发fail信号后上管打开，下管关闭
#define MCPWM_FAIL_IO_LOW  0x55 // 触发fail信号后上管关闭，下管打开
#define MCPWM_FAIL_IO_OFF  0    // 触发fail信号后上下管全关

// fail信号来源配置
#define MCPWM_FAIL0_OFF        (0)                         // 关闭fail0
#define MCPWM_FAIL0_CMP0_H     (BIT8 | BIT4)               // 使用cmp0的高电平作为fail0的输入
#define MCPWM_FAIL0_CMP0_L     (BIT8 | BIT4 | BIT2)        // 使用cmp0的低电平作为fail0的输入
#define MCPWM_FAIL0_BKIN0_H    (BIT4)                      // 使用BKIN0的高电平作为fail0的输入
#define MCPWM_FAIL0_BKIN0_L    (BIT4 | BIT2)               // 使用BKIN0的低电平作为fail0的输入
#define MCPWM_FAIL0_CLU_OUT0_H (BIT9 | BIT4)               // 使用CLU_OUT0的高电平作为fail0的输入
#define MCPWM_FAIL0_CLU_OUT0_L (BIT9 | BIT4 | BIT2)        // 使用CLU_OUT0的低电平作为fail0的输入
#define MCPWM_FAIL0_CLU_OUT1_H (BIT9 | BIT8 | BIT4)        // 使用CLU_OUT1的高电平作为fail0的输入
#define MCPWM_FAIL0_CLU_OUT1_L (BIT9 | BIT8 | BIT4 | BIT2) // 使用CLU_OUT1的低电平作为fail0的输入

// fail信号来源配置
#define MCPWM_FAIL1_OFF        (0)                           // 关闭fail1
#define MCPWM_FAIL1_CMP1_H     (BIT10 | BIT5)                // 使用cmp1的高电平作为fail1的输入
#define MCPWM_FAIL1_CMP1_L     (BIT10 | BIT5 | BIT3)         // 使用cmp1的低电平作为fail1的输入
#define MCPWM_FAIL1_BKIN1_H    (BIT5)                        // 使用BKIN1的高电平作为fail1的输入
#define MCPWM_FAIL1_BKIN1_L    (BIT5 | BIT3)                 // 使用BKIN1的低电平作为fail1的输入
#define MCPWM_FAIL1_CLU_OUT2_H (BIT11 | BIT5)                // 使用CLU_OUT2的高电平作为fail1的输入
#define MCPWM_FAIL1_CLU_OUT2_L (BIT11 | BIT5 | BIT3)         // 使用CLU_OUT2的低电平作为fail1的输入
#define MCPWM_FAIL1_CLU_OUT3_H (BIT11 | BIT10 | BIT5)        // 使用CLU_OUT3的高电平作为fail1的输入
#define MCPWM_FAIL1_CLU_OUT3_L (BIT11 | BIT10 | BIT5 | BIT3) // 使用CLU_OUT3的低电平作为fail1的输入

/**
 * @brief 模块使能
 * @param MCPWMx MCPWM模块
 */
void MCPWM_Enable(MCPWM_TypeDef *MCPWMx);
/**
 * @brief 模块失能
 * @param MCPWMx MCPWM模块
 */
void MCPWM_Disable(MCPWM_TypeDef *MCPWMx);
/**
 * @brief 模块复位
 * @param MCPWMx MCPWM模块
 */
void MCPWM_Reset(MCPWM_TypeDef *MCPWMx);
/**
 * @brief 模块初始化
 */
void MCPWM_Init(MCPWM_TypeDef *MCPWMx, MCPWM_InitTypeDef *MCPWM_InitStruct);
/**
 * @brief mcpwm配置结构体初始化
 */
void MCPWM_StructInit(MCPWM_InitTypeDef *MCPWM_InitStruct);
/**
 * @brief 设置MCPWM输出状态
 * @param MCPWMx MCPWM模块
 * @param state 输出状态 1打开输出 0关闭输出
 */
void MCPWM_SetOutputState(MCPWM_TypeDef *MCPWMx, uint8_t state);
/**
 * @brief 设置MCPWM输出值
 * @param MCPWMx MCPWM模块
 * @param chn 通道号 0-3
 * @param p 上管打开时间，取值范围-th到th
 * @param n 下管打开时间，取值范围-th到th
 */
void MCPWM_SetOutputVal(MCPWM_TypeDef *MCPWMx, uint8_t chn, int16_t p, int16_t n);
/**
 * @brief 设置MCPWM触发ADC事件时间
 * @param MCPWMx MCPWM模块
 * @param tmr0 事件0时间
 * @param tmr1 事件1时间
 * @param tmr2 事件2时间
 * @param tmr3 事件3时间
 */
void MCPWM_SetTMR(MCPWM_TypeDef *MCPWMx, int16_t tmr0, int16_t tmr1, int16_t tmr2, int16_t tmr3);
/**
 * @brief 设置IO配置
 * @param MCPWMx MCPWM模块
 * @param io0 IO0配置
 * @param io1 IO1配置
 * @param io2 IO2配置
 * @param io3 IO3配置
 * @note 由于mcpwm的io0和io1是一个寄存器，io2和io3是一个寄存器，所以需要同时配置
 */
void MCPWM_SetIOConfig(MCPWM_TypeDef *MCPWMx, uint16_t io0, uint16_t io1, uint16_t io2, uint16_t io3);
/**
 * @brief 开始计数
 * @param MCPWMx MCPWM模块
 */
void MCPWM_StartCount(MCPWM_TypeDef *MCPWMx);
/**
 * @brief 停止计数
 * @param MCPWMx MCPWM模块
 */
void MCPWM_StopCount(MCPWM_TypeDef *MCPWMx);
/**
 * @brief 获取MCPWM中断标志
 * @param MCPWMx MCPWM模块
 * @param MCPWM_IF_x 中断标志位
 * @return 1中断发生 0中断未发生
 */
uint16_t MCPWM_GetIRQFlag(MCPWM_TypeDef *MCPWMx, uint32_t MCPWM_IF_x);
/**
 * @brief 获取MCPWM事件
 * @param MCPWMx MCPWM模块
 * @param MCPWM_IF_x 中断标志位
 * @return 1事件发生 0事件未发生
 * @note 事件和中断的区别在于事件只是一个标志位，用于在中断函数外部判断事件是否发生
 */
uint16_t MCPWM_GetIfFlag(MCPWM_TypeDef *MCPWMx, uint32_t MCPWM_IF_x);
/**
 * @brief 获取MCPWM错误中断标志
 * @param MCPWMx MCPWM模块
 * @param MCPWM_EIF_x 错误中断标志位
 * @return 1事件发生 0事件未发生
 */
uint16_t MCPWM_GetEifFlag(MCPWM_TypeDef *MCPWMx, uint32_t MCPWM_IF_x);
/**
 * @brief 获取CMPWM错误中断标志
 * @param MCPWMx MCPWM模块
 * @param MCPWM_EIF_x 错误中断标志位
 * @return 1中断发生 0中断未发生
 */
uint16_t MCPWM_GetErrorIRQFlag(MCPWM_TypeDef *MCPWMx, uint32_t MCPWM_EIF_x);
/**
 * @brief 清除MCPWM中断标志
 * @param MCPWMx MCPWM模块
 * @param MCPWM_IF_x 中断标志位
 */
void MCPWM_ClearIRQFlag(MCPWM_TypeDef *MCPWMx, uint32_t MCPWM_IF_x);
/**
 * @brief 清除MCPWM错误中断标志
 * @param MCPWMx MCPWM模块
 * @param MCPWM_EIF_x 错误中断标志位
 */
void MCPWM_ClearErrorIRQFlag(MCPWM_TypeDef *MCPWMx, uint32_t MCPWM_EIF_x);

/**
 * @brief 获取当前计数器门限值
 * @param MCPWMx MCPWM模块
 * @return 当前计数器门限值
 */
int16_t MCPWM_GetCountTh(MCPWM_TypeDef *MCPWMx);
/**
 * @brief 获取当前计数器值
 * @param MCPWMx MCPWM模块
 * @return 当前计数器值
 */
int16_t MCPWM_GetCountVal(MCPWM_TypeDef *MCPWMx);

// 通过宏定义简化中断执行时间
// 中断标志位判断
#define MCPWM_IRQ_UP(MCPWMx)    (MCPWMx->IF0 & MCPWM->IE0 & MCPWM_IF_UP)     // 时基 0 更新事件 MCPWM0_TH0/MCPWM0_TH00~MCPWM0_TH21/MCPWM0_TMR 等寄存器更新到 MCPWM 实际运行系统的中断事件。
#define MCPWM_IRQ_TMR3(MCPWMx)  (MCPWMx->IF0 & MCPWM->IE0 & MCPWM_IF_TMR3)   // MCPWM0_CNT0 等于 MCPWM0_TMR3 中断事件。
#define MCPWM_IRQ_TMR2(MCPWMx)  (MCPWMx->IF0 & MCPWM->IE0 & MCPWM_IF_TMR2)   // MCPWM0_CNT0 等于 MCPWM0_TMR2 中断事件。
#define MCPWM_IRQ_TMR1(MCPWMx)  (MCPWMx->IF0 & MCPWM->IE0 & MCPWM_IF_TMR1)   // MCPWM0_CNT0 等于 MCPWM0_TMR1 中断事件。
#define MCPWM_IRQ_TMR0(MCPWMx)  (MCPWMx->IF0 & MCPWM->IE0 & MCPWM_IF_TMR0)   // MCPWM0_CNT0 等于 MCPWM0_TMR0 中断事件。
#define MCPWM_IRQ_TH21(MCPWMx)  (MCPWMx->IF0 & MCPWM->IE0 & MCPWM_IF_TH21)   // MCPWM0_CNT0 等于 MCPWM0_TH21 中断事件。
#define MCPWM_IRQ_TH20(MCPWMx)  (MCPWMx->IF0 & MCPWM->IE0 & MCPWM_IF_TH20)   // MCPWM0_CNT0 等于 MCPWM0_TH20 中断事件。
#define MCPWM_IRQ_TH11(MCPWMx)  (MCPWMx->IF0 & MCPWM->IE0 & MCPWM_IF_TH11)   // MCPWM0_CNT0 等于 MCPWM0_TH11 中断事件。
#define MCPWM_IRQ_TH10(MCPWMx)  (MCPWMx->IF0 & MCPWM->IE0 & MCPWM_IF_TH10)   // MCPWM0_CNT0 等于 MCPWM0_TH10 中断事件。
#define MCPWM_IRQ_TH01(MCPWMx)  (MCPWMx->IF0 & MCPWM->IE0 & MCPWM_IF_TH01)   // MCPWM0_CNT0 等于 MCPWM0_TH01 中断事件。
#define MCPWM_IRQ_TH00(MCPWMx)  (MCPWMx->IF0 & MCPWM->IE0 & MCPWM_IF_TH00)   // MCPWM0_CNT0 等于 MCPWM0_TH00 中断事件。
#define MCPWM_IRQ_T1(MCPWMx)    (MCPWMx->IF0 & MCPWM->IE0 & MCPWM_IF_T1)     // t1 事件，MCPWM0_CNT0 等于 0 中断事件。
#define MCPWM_IRQ_T0(MCPWMx)    (MCPWMx->IF0 & MCPWM->IE0 & MCPWM_IF_T0)     // t0 事件，MCPWM0_CNT0 等于 MCPWM0_TH 中断事件。
#define MCPWM_IRQ_FAIL0(MCPWMx) (MCPWMx->EIF & MCPWM->EIE & MCPWM_EIF_FAIL0) // FAIL1 中断源事件。
#define MCPWM_IRQ_FAIL1(MCPWMx) (MCPWMx->EIF & MCPWM->EIE & MCPWM_EIF_FAIL1) // FAIL0 中断源事件。

// 中断标志位获取，和MCPWM_IRQ_x的区别是不进行中断使能位的判断
#define MCPWM_GET_IRQ_UP(MCPWMx)    (MCPWMx->IF0 & MCPWM_IF_UP)     // 时基 0 更新事件 MCPWM0_TH0/MCPWM0_TH00~MCPWM0_TH21/MCPWM0_TMR 等寄存器更新到 MCPWM 实际运行系统的中断事件。
#define MCPWM_GET_IRQ_TMR3(MCPWMx)  (MCPWMx->IF0 & MCPWM_IF_TMR3)   // MCPWM0_CNT0 等于 MCPWM0_TMR3 中断事件。
#define MCPWM_GET_IRQ_TMR2(MCPWMx)  (MCPWMx->IF0 & MCPWM_IF_TMR2)   // MCPWM0_CNT0 等于 MCPWM0_TMR2 中断事件。
#define MCPWM_GET_IRQ_TMR1(MCPWMx)  (MCPWMx->IF0 & MCPWM_IF_TMR1)   // MCPWM0_CNT0 等于 MCPWM0_TMR1 中断事件。
#define MCPWM_GET_IRQ_TMR0(MCPWMx)  (MCPWMx->IF0 & MCPWM_IF_TMR0)   // MCPWM0_CNT0 等于 MCPWM0_TMR0 中断事件。
#define MCPWM_GET_IRQ_TH21(MCPWMx)  (MCPWMx->IF0 & MCPWM_IF_TH21)   // MCPWM0_CNT0 等于 MCPWM0_TH21 中断事件。
#define MCPWM_GET_IRQ_TH20(MCPWMx)  (MCPWMx->IF0 & MCPWM_IF_TH20)   // MCPWM0_CNT0 等于 MCPWM0_TH20 中断事件。
#define MCPWM_GET_IRQ_TH11(MCPWMx)  (MCPWMx->IF0 & MCPWM_IF_TH11)   // MCPWM0_CNT0 等于 MCPWM0_TH11 中断事件。
#define MCPWM_GET_IRQ_TH10(MCPWMx)  (MCPWMx->IF0 & MCPWM_IF_TH10)   // MCPWM0_CNT0 等于 MCPWM0_TH10 中断事件。
#define MCPWM_GET_IRQ_TH01(MCPWMx)  (MCPWMx->IF0 & MCPWM_IF_TH01)   // MCPWM0_CNT0 等于 MCPWM0_TH01 中断事件。
#define MCPWM_GET_IRQ_TH00(MCPWMx)  (MCPWMx->IF0 & MCPWM_IF_TH00)   // MCPWM0_CNT0 等于 MCPWM0_TH00 中断事件。
#define MCPWM_GET_IRQ_T1(MCPWMx)    (MCPWMx->IF0 & MCPWM_IF_T1)     // t1 事件，MCPWM0_CNT0 等于 0 中断事件。
#define MCPWM_GET_IRQ_T0(MCPWMx)    (MCPWMx->IF0 & MCPWM_IF_T0)     // t0 事件，MCPWM0_CNT0 等于 MCPWM0_TH 中断事件。
#define MCPWM_GET_IRQ_FAIL0(MCPWMx) (MCPWMx->EIF & MCPWM_EIF_FAIL0) // FAIL1 中断源事件。
#define MCPWM_GET_IRQ_FAIL1(MCPWMx) (MCPWMx->EIF & MCPWM_EIF_FAIL1) // FAIL0 中断源事件。

// 中断标志位清除
#define MCPWM_IRQ_CLEAR_UP(MCPWMx)    MCPWMx->IF0 = MCPWM_IF_UP     // 时基 0 更新事件 MCPWM0_TH0/MCPWM0_TH00~MCPWM0_TH21/MCPWM0_TMR 等寄存器更新到 MCPWM 实际运行系统的中断事件。
#define MCPWM_IRQ_CLEAR_TMR3(MCPWMx)  MCPWMx->IF0 = MCPWM_IF_TMR3   // MCPWM0_CNT0 等于 MCPWM0_TMR3 中断事件。
#define MCPWM_IRQ_CLEAR_TMR2(MCPWMx)  MCPWMx->IF0 = MCPWM_IF_TMR2   // MCPWM0_CNT0 等于 MCPWM0_TMR2 中断事件。
#define MCPWM_IRQ_CLEAR_TMR1(MCPWMx)  MCPWMx->IF0 = MCPWM_IF_TMR1   // MCPWM0_CNT0 等于 MCPWM0_TMR1 中断事件。
#define MCPWM_IRQ_CLEAR_TMR0(MCPWMx)  MCPWMx->IF0 = MCPWM_IF_TMR0   // MCPWM0_CNT0 等于 MCPWM0_TMR0 中断事件。
#define MCPWM_IRQ_CLEAR_TH21(MCPWMx)  MCPWMx->IF0 = MCPWM_IF_TH21   // MCPWM0_CNT0 等于 MCPWM0_TH21 中断事件。
#define MCPWM_IRQ_CLEAR_TH20(MCPWMx)  MCPWMx->IF0 = MCPWM_IF_TH20   // MCPWM0_CNT0 等于 MCPWM0_TH20 中断事件。
#define MCPWM_IRQ_CLEAR_TH11(MCPWMx)  MCPWMx->IF0 = MCPWM_IF_TH11   // MCPWM0_CNT0 等于 MCPWM0_TH11 中断事件。
#define MCPWM_IRQ_CLEAR_TH10(MCPWMx)  MCPWMx->IF0 = MCPWM_IF_TH10   // MCPWM0_CNT0 等于 MCPWM0_TH10 中断事件。
#define MCPWM_IRQ_CLEAR_TH01(MCPWMx)  MCPWMx->IF0 = MCPWM_IF_TH01   // MCPWM0_CNT0 等于 MCPWM0_TH01 中断事件。
#define MCPWM_IRQ_CLEAR_TH00(MCPWMx)  MCPWMx->IF0 = MCPWM_IF_TH00   // MCPWM0_CNT0 等于 MCPWM0_TH00 中断事件。
#define MCPWM_IRQ_CLEAR_T1(MCPWMx)    MCPWMx->IF0 = MCPWM_IF_T1     // t1 事件，MCPWM0_CNT0 等于 0 中断事件。
#define MCPWM_IRQ_CLEAR_T0(MCPWMx)    MCPWMx->IF0 = MCPWM_IF_T0     // t0 事件，MCPWM0_CNT0 等于 MCPWM0_TH 中断事件。
#define MCPWM_IRQ_CLEAR_FAIL0(MCPWMx) MCPWMx->EIF = MCPWM_EIF_FAIL0 // FAIL1 中断源事件。
#define MCPWM_IRQ_CLEAR_FAIL1(MCPWMx) MCPWMx->EIF = MCPWM_EIF_FAIL1 // FAIL0 中断源事件。
#endif
