#include <Myproject.h>


/**
    @function     Bus_Voltage_Check
    @brief        母线电压检测
    @date         2025-11-17
*/
void Bus_Voltage_Check(void)
{
    static uint16_t DelayCnt = 0;
    
    if (DelayCnt < 500)
    {
        DelayCnt++;
        return;
    }
    
    // 过压检测
    FAULT_COUNT_UPDOWN(faultCheck.CheckCnt.OverVolt,
        (faultCheck.BusVoltage > OVER_VOLTAGE_PROTECT), 300, VDC_OVER);
    // 欠压检测
    FAULT_COUNT_UPDOWN(faultCheck.CheckCnt.UnderVolt,
        (faultCheck.BusVoltage < UNDER_VOLTAGE_PROTECT), 300, VDC_UNDER);
}


/**
    @function     MOS_Temper_Check
    @brief        温度检测
    @date         2025-11-17
*/
void MOS_Temper_Check(void)
{
    FAULT_COUNT_UPDOWN(faultCheck.CheckCnt.OverTemper,
        (faultCheck.NTCTemper <= TEMP_PROT_VALUE), TEMP_DECTTIME, TEMPER_NTC);
}

/**
    @function     Bus_Curr_Check
    @brief        母线电流检测
    @date         2025-11-17
*/
void Bus_Curr_Check(void)
{
    FAULT_COUNT_UPDOWN(faultCheck.CheckCnt.OverCurr,
        (faultCheck.BusCurr >= BUS_CURR_PROT_VALUE), BUS_CURR_DECTTIME, SOFT_OVER_CURR);
}

/**
    @function     Motor_Stall_Check
    @brief        电机堵转检测
    @date         2025-11-17
*/
void Motor_Stall_Check(void)
{
    if (faultCheck.CheckCnt.DelayStall < 500)
    { faultCheck.CheckCnt.DelayStall ++;}
    else
    {
        // 1.持续3秒反电动势过小
        if (faultCheck.BackEMF < ES_THRESHOLD_LOW)
        {
            faultCheck.CheckCnt.EsValue++;
            
            if (faultCheck.CheckCnt.EsValue > 3000)
            { FaultSource = MOTOR_STALL; }
        }
        // 2.超过对应转速时 反电动势过低
        else if ((faultCheck.BackEMF < ES_THRESHOLD_HIGH) && (faultCheck.ActualSpeed > ES_THRESHOLD_SPEED))
        {
            faultCheck.CheckCnt.EsValue++;
            
            if (faultCheck.CheckCnt.EsValue > 3000)
            { FaultSource = MOTOR_STALL; }
        }
        else if (faultCheck.CheckCnt.EsValue)
        {faultCheck.CheckCnt.EsValue--;}
        
        // 3.速度超出极限转速
        if (faultCheck.ActualSpeed < STALL_SPEED_MIN || faultCheck.ActualSpeed > STALL_SPEED_MAX)
        {
            faultCheck.CheckCnt.StallSpeed++;
            
            if (faultCheck.CheckCnt.StallSpeed > 3000)
            { FaultSource = MOTOR_STALL; }
        }
        else if (faultCheck.CheckCnt.StallSpeed)
        {faultCheck.CheckCnt.StallSpeed -- ;}
    }
    
    // 4.长时间未进闭环
    FAULT_COUNT_UPDOWN(faultCheck.CheckCnt.CloseLoop,
        (loopCtrl.State == OPEN_MODE), 1000, MOTOR_STALL);
}


/**
    @function     Phase_Curr_Check
    @brief        缺相检测
    @date         2024-06-17
*/
void Phase_Curr_Check(void)
{
    // 运行后等待计数
    if (faultCheck.CheckCnt.DelayPhase < 500)
    {
        faultCheck.CheckCnt.DelayPhase++;
        return;
    }
    
    // 检测
    if (faultCheck.CheckCnt.LossPhase < LOSS_PHASE_CYCLE)
    {
        faultCheck.MaxIa = FOC__IAMAX;
        faultCheck.MaxIb = FOC__IBMAX;
        faultCheck.MaxIc = FOC__ICMAX;
        faultCheck.CheckCnt.LossPhase++;
        return;
    }
    
    faultCheck.CheckCnt.LossPhase = 0;
    // 各相独立更新缺相计数，逻辑与原代码完全一致
    UPDATE_PHASE_LOSS_CNT(faultCheck.MaxIa,
        faultCheck.MaxIb, faultCheck.MaxIc, faultCheck.CheckCnt.PhaseA);
    UPDATE_PHASE_LOSS_CNT(faultCheck.MaxIb,
        faultCheck.MaxIa, faultCheck.MaxIc, faultCheck.CheckCnt.PhaseB);
    UPDATE_PHASE_LOSS_CNT(faultCheck.MaxIc,
        faultCheck.MaxIa, faultCheck.MaxIb, faultCheck.CheckCnt.PhaseC);
    // 清零变量
    faultCheck.MaxIa = 0;
    faultCheck.MaxIa = 0;
    faultCheck.MaxIa = 0;
    SetBit(FOC_CR2, ICLR);
    
    if ((faultCheck.CheckCnt.PhaseA > 10) ||
        (faultCheck.CheckCnt.PhaseB > 10) ||
        (faultCheck.CheckCnt.PhaseC > 10))
    { FaultSource = FCT_LOSS_PHASE; }
}

/**
    @function     Run_Power_Check
    @brief        运行功率检测
    @date         2024-06-17
*/
static void Run_Power_Check(void)
{
    FAULT_COUNT_UPDOWN(faultCheck.CheckCnt.OverPower,
        (faultCheck.Power > OVER_POWER_VAL), OP_DECTTIME, OVER_POWER);
}

/**
    @function     Recovery_Fault_Handle
    @brief        故障恢复
    @date         2025-11-19
*/
static void Recovery_Fault_Handle(void)
{
    switch (FaultSource)
    {
        default:
            break;
            
        // 无故障 直接返回
        case SYS_NO_FAULT:
            return;
            
        // 欠压恢复
        case VDC_UNDER:
            if (faultCheck.BusVoltage > UNDER_VOLTAGE_RECOVER)
            { RECOVER_DELAY(faultCheck.RecoverCnt.UnderVolt); }
            
            break;
            
        // 过压恢复
        case VDC_OVER:
            if (faultCheck.BusVoltage < OVER_VOLTAGE_RECOVER)
            { RECOVER_DELAY(faultCheck.RecoverCnt.OverVolt); }
            
            break;
            
        // 过温恢复
        case TEMPER_NTC:
            if (faultCheck.NTCTemper >= TEMP_RECOVER_VALUE)
            { RECOVER_DELAY(faultCheck.RecoverCnt.OverTemper); }
            
            break;
            
        // 缺相恢复
        case FCT_LOSS_PHASE:
            RECOVER_DELAY(faultCheck.RecoverCnt.PhaseLoss);
            break;
            
        // 堵转恢复
        case MOTOR_STALL:
            RECOVER_DELAY(faultCheck.RecoverCnt.Stall);
            break;
            
        // 过流恢复
        case HARD_OVER_CURR:
        case SOFT_OVER_CURR:
            RECOVER_DELAY(faultCheck.RecoverCnt.OverCurr);
            break;
            
        // 过功率恢复
        case OVER_POWER:
            RECOVER_DELAY(faultCheck.RecoverCnt.OverPower);
            break;
            
        // PWM丢失
        case LOSS_PWM:
            RECOVER_DELAY(faultCheck.RecoverCnt.PWMLoss);
            break;
            
        // 串口丢失
        case LOSS_UART:
            RECOVER_DELAY(faultCheck.RecoverCnt.UartLoss);
            break;
    }
}

/**
    @function     Motor_Fault_Handle
    @brief        故障检测与恢复
    @date         2024-06-17
*/
void Motor_Fault_Handle(void)
{
    if ((sysState == MOTOR_RUN) || (sysState == MOTOR_STOP))
    {
        // 母线电流检测
        #if (PRT_SW_OVER_CURR_EN)
        Bus_Curr_Check();
        #endif
        // 相线电流检测
        #if (PRT_PHASE_LOSS_EN)
        Phase_Curr_Check();
        #endif
        // 电机运行状态检测
        #if (PRT_MOTOR_STALL_EN)
        Motor_Stall_Check();
        #endif
        // 功率检测
        #if (PRT_OVER_POWER_EN)
        Run_Power_Check();
        #endif
    }
    
    if (FaultSource == SYS_NO_FAULT)
    {
        // 电压检测
        #if (PRT_VDC_EN)
        Bus_Voltage_Check();
        #endif
        // 温度检测
        #if (PRT_OVER_TEMPER_EN)
        MOS_Temper_Check();
        #endif
    }
    
    // 故障自动恢复
    #if (AUTO_RECOVER_FAULT_EN)
    Recovery_Fault_Handle();
    #endif
}


