#include <Myproject.h>

MotStaType   mcState;
MotStaM      McStaSet;

/**
    @function     Motor_Control_State
    @brief        电机控制状态机 负责状态跳转
    @date         2025-11-03
*/
void Motor_Control_State(void)
{
    // 故障直接跳转Fault
    if (mcFaultSource != FaultNoSource)
    { mcState = mcFault; }
    // 非Ready状态检测到关机信号跳转Stop
    else if ((isCtrlPowOn == false) && (mcState != mcReady))
    {
        // 若当前为Run 配置停机时间再跳转Stop
        if (mcState == mcRun)
        { mcFocCtrl.State_Count = 30000; }
        
        mcState = mcStop;
    }
    
    switch (mcState)
    {
        case mcReady:
        {
            switch (currOffset.OffsetCalib)
            {
                // 初始化状态
                case CALIB_INIT:
                {
                    if (powerControl.PowerSate == POWER_RUN)
                    {
                        ClrBit(DRV_CR, FOCEN);
                        MOE = 0;
                        // 使能ADC转换通道
                        SetBit(ADC_MASK, CH1EN | CH0EN);
                        // 电流校准变量初始化
                        memset(&currOffset, 0, sizeof(Curr_Offset_t));
                        // 配置初始值
                        currOffset.IuOffsetSum = 16383;
                        currOffset.IvOffsetSum = 16383;
                        currOffset.IwBusOffsetSum = 16383;
                        // 跳转状态
                        currOffset.OffsetCalib = GET_OFFSET;
                    }
                    
                    break;
                }
                
                // 检查状态
                case GET_OFFSET:
                {
                    SetBit(ADC_CR, ADCBSY);
                    
                    while (ReadBit(ADC_CR, ADCBSY));
                    
                    currOffset.IuOffsetSum += ((ADC0_DR & 0x7ff8));
                    currOffset.IuOffset = currOffset.IuOffsetSum >> 4;
                    currOffset.IuOffsetSum -= currOffset.IuOffset;
                    currOffset.IvOffsetSum += ((ADC1_DR & 0x7ff8));
                    currOffset.IvOffset = currOffset.IvOffsetSum >> 4;
                    currOffset.IvOffsetSum -= currOffset.IvOffset;
                    currOffset.IwBusOffset = currOffset.IvOffset;
                    
                    if (++currOffset.OffsetCount > 1000)
                    {
                        //进入偏置电压错误保护
                        if (((currOffset.IuOffset > 19959) || (currOffset.IuOffset < 10107)) ||
                            ((currOffset.IvOffset > 19959) || (currOffset.IvOffset < 10107)))
                        {
                            currOffset.OffsetCalib = CALIB_INIT;
                            mcFaultSource = FaultIbusOffset;
                            FaultProcess();
                        }
                        else
                        { currOffset.OffsetCalib = OFFSET_READY; }
                    }
                    
                    break;
                }
                
                // 启动状态
                case OFFSET_READY:
                {
                    if (isCtrlPowOn)
                    {
                        mcState = mcInit;
                        // 关闭软件电流采样的ADC
                        ClrBit(ADC_MASK, CH1EN | CH0EN);
                        currOffset.OffsetCalib = CALIB_INIT;
                        ClrBit(DRV_CR, DRVEN);
                        _nop_(); _nop_(); _nop_(); _nop_();
                        SetBit(DRV_CR, DRVEN);
                    }
                    
                    break;
                }
            }
            
            break;
        }
        
        case mcInit:
        {
			if (motorControl.DCBus > UNDER_RECOVER_VALUE)
            {
                // 关闭软件电流采样的ADC
                mcFaultSource = 0;
                memset(&mcFaultDect, 0, sizeof(FaultVarible));
                memset(&mcFocCtrl, 0, sizeof(FOCCTRL));
                McStaSet.SetMode = 0;
                // PI控制器初始化
                HW_Zero_PI_Init();
                // 弱磁初始化
                #if (FiledWeakenCompEnable)
                memset(&mcFieldWeaken, 0, sizeof(FieldWeakeningTypeDef));
                HW_One_PI_Init();
                #endif
                // 环路配置
                #if (SPEED_CONTROL_MODE)
                motorControl.RampInc = MOTOR_SPEED_INC;
                motorControl.RampDec = MOTOR_SPEED_DEC;
                #endif
                // 此模块不需要预充电
                #if (PRE_DRIVER_CHARGE)
                mcState = mcCharge;
                mcFocCtrl.ChargeStep = 0;
                mcFocCtrl.State_Count = 0;
                #else
                mcState = mcAlign;
                mcFocCtrl.State_Count = Align_Time;
                #endif
            }
            break;
        }
        
        #if (PRE_DRIVER_CHARGE)
        
        case mcCharge:
        {
            switch (mcFocCtrl.ChargeStep)
            {
                case 0:
                {
                    // 配置占空比
                    DRV_DR = Calib_Duty * DRV_ARR;
                    // DRV_CTL：PWM来源选择
                    // OCS = 0, DRV_COMR
                    // OCS = 1, FOC/SVPWM/SPWM
                    ClrBit(DRV_CR, OCS);
                    mcFocCtrl.ChargeStep = 1;
                    mcFocCtrl.State_Count = 30;
                    break;
                }
                
                // U相下桥臂通
                case 1:
                {
                    DRV_CMR |= 0x01;
                    MOE = 1;
                    break;
                }
                
                // V相下桥臂导通
                case 2:
                {
                    DRV_CMR |= 0x04;
                    break;
                }
                
                // W相下桥臂导通
                case 3:
                {
                    DRV_CMR |= 0x10;
                    break;
                }
                
                case 4:
                {
                    #if (1)
                    DRV_CMR |= 0x3F;
                    #else
                    MOE = 0;
                    mcState = mcAlign;
                    mcFocCtrl.State_Count = Align_Time;
                    #endif
                    break;
                }
            }
            
            if ((mcFocCtrl.State_Count == 0) && (mcFocCtrl.ChargeStep != 4 ))
            {
                mcFocCtrl.ChargeStep ++;
                mcFocCtrl.State_Count = 30;
            }
            
            break;
        }
        
        #endif
        
        case mcAlign:
        {
            Motor_Align();
            break;
        }
        
        case mcStart:   // 配置电机启动参数，进入mcRun状态。
        {
            Motor_Open();
            break;
        }
        
        case mcRun:     // 运行状态，若运行状态的给定变为0，进入mcStop状态。
        {
            break;
        }
        
        case mcStop:
        {
            #if (StopBrakeFlag)
        
            if (motorControl.ActualSpeed < MOTOR_STOP_SPEED)
            {
                MOE = 0;
                FOC_CR1 = 0x00;
                ClrBit(DRV_CR, FOCEN);
                DRV_DR   = DRV_ARR + 1;
                DRV_CMR  = 0x00;
                DRV_CMR |= 0x015;     // 三相下桥臂通，刹车
                ClrBit(DRV_CR, OCS);  // OCS = 0, DRV_COMR;OCS = 1, FOC/SVPWM/SPWM
                MOE = 1;
                mcState  = mcBrake;
                mcFocCtrl.State_Count = StopWaitTime;
            }
            
            #else
            {
                mcState = mcReady;
                FOC_CR1 = 0x00;
                ClrBit(DRV_CR, FOCEN);   //关闭FOC
                MOE = 0;
            }
            #endif
            break;
        }
        
        case mcBrake:
        {
            if (isCtrlPowOn)
            {
                mcState = mcReady;
                mcFocCtrl.State_Count = 0;      //单位：1ms  强制关机时间
            }
            else if (mcFocCtrl.State_Count == 0)
            {
                mcState = mcReady;
                MOE = 0;
                ClrBit(DRV_CR, FOCEN);
            }
            
            break;
        }
        
        case mcFault:
        {
            if (mcFaultSource == FaultNoSource)
            { mcState = mcReady;}
            
            break;
        }
        
        default:
        {
            mcState = mcReady;
            break;
        }
    }
}


/**
    @function     Tick_Task
    @brief        周期任务
    @date         2025-11-03
*/
void Tick_Task(void)
{
    if ((mcState == mcStart) || (mcState == mcRun) || (mcState == mcStop))
    {
        mcFocCtrl.Powerlpf =  LPF_Zero_Update(FOC__POW, mcFocCtrl.Powerlpf, LPF_K(1.0));
        mcFocCtrl.UDFlt =  LPF_Zero_Update(FOC__UD, mcFocCtrl.UDFlt, LPF_K(30.0));          //LPF_K(30.0)
        mcFocCtrl.UQFlt =  LPF_Zero_Update(FOC__UQ, mcFocCtrl.UQFlt, LPF_K(30.0));          //LPF_K(30.0)
        motorControl.ActualSpeed = LPF_Zero_Update(FOC__EOME, motorControl.ActualSpeed, LPF_K(71.0));
        motorControl.BackEMF = LPF_Zero_Update(FOC__EMF, motorControl.BackEMF, LPF_K(5.0));
        
        if (mcFocCtrl.Powerlpf <= 0)
        {mcFocCtrl.Powerlpf = 0;}
    }
    else
    {
        mcFocCtrl.Powerlpf = 0;
        motorControl.ActualSpeed = 0;
        motorControl.BackEMF = 0;
    }
    
    // StarRampDealwith();
}
