/**
    @copyright None
    @file      led.c
    @author    Comment Vivre
    @date      2025-12-19
    @brief     None
*/

#include <MyProject.h>

LED_Control_t ledCtrl;



/**
    @function     LED_GPIO_Init
    @brief        LED GPIO初始化
    @date         2025-12-19
*/
void LED_GPIO_Init(void)
{
    SetBit(LED_PXIN, LED_PINX);
    LED_OFF;
}

/**
    @function     LED_State_Display
    @brief        指示运行与故障代码
    @param[in]    Xn0: [输入/出] 故障代码
    @date         2025-05-30
*/
void LED_State_Display(unsigned char Xn0)
{
    // 故障指示状态下 检测到故障码清除 立刻清除故障
    if ((ledCtrl.ledState != LED_STATE_OFF ) && (ledCtrl.ledState != LED_STATE_ON))
    {
        if (Xn0 == 0)
        {
            LED_OFF;
            ledCtrl.ledState = LED_STATE_OFF;
            return;
        }
    }
    
    switch (ledCtrl.ledState)
    {
        // 关闭状态
        case LED_STATE_OFF:
        
            // 存在故障 切入故障状态 清零计数
            if (Xn0)
            {
                ledCtrl.ledState = LED_STATE_FAULT_HIGH_BLINK;
                ledCtrl.PauseDelayCnt = 0;
                ledCtrl.BlinkCnt = 0;
                ledCtrl.FaultHighBit = Xn0 >> 4;
                ledCtrl.FaultLowBit = Xn0 & 0x0F;
                LED_OFF;
            }
            // 开启状态且无故障 切入开启状态并打开LED
            else if (isCtrlPowOn)
            {
                ledCtrl.ledState = LED_STATE_ON;
                LED_ON;
            }
            
            break;
            
        // 开启状态
        case LED_STATE_ON:
        
            // 故障或停止时 关闭LED并切回关闭状态
            if (!isCtrlPowOn || Xn0)
            {
                ledCtrl.ledState = LED_STATE_OFF;
                LED_OFF;
            }
            
            break;
            
        // 高4位闪烁
        case LED_STATE_FAULT_HIGH_BLINK:
            if (ledCtrl.FaultHighBit == 0)
            {
                LED_OFF;
                ledCtrl.BlinkCnt = 0;
                ledCtrl.PauseDelayCnt = 0;
                ledCtrl.ledState = LED_STATE_FAULT_HIGH_GAP;
                break;
            }
            
            if (++ledCtrl.PauseDelayCnt >= 500)
            {
                ledCtrl.PauseDelayCnt = 0;
                LEDPinONOFF;
                
                if (LED_PIN)   // 灭灯计数
                {
                    ledCtrl.BlinkCnt++;
                    
                    if (ledCtrl.BlinkCnt >= ledCtrl.FaultHighBit)
                    {
                        LED_OFF;
                        ledCtrl.BlinkCnt = 0;
                        ledCtrl.ledState = LED_STATE_FAULT_HIGH_GAP;
                    }
                }
            }
            
            break;
            
        // 高低位间隔 1s
        case LED_STATE_FAULT_HIGH_GAP:
            if (++ledCtrl.PauseDelayCnt >= 1000)
            {
                ledCtrl.PauseDelayCnt = 0;
                ledCtrl.ledState = LED_STATE_FAULT_LOW_BLINK;
            }
            
            break;
            
        // 低4位闪烁
        case LED_STATE_FAULT_LOW_BLINK:
            if (ledCtrl.FaultLowBit == 0)
            {
                LED_OFF;
                ledCtrl.BlinkCnt = 0;
                ledCtrl.PauseDelayCnt = 0;
                ledCtrl.ledState = LED_STATE_FAULT_CYCLE_GAP;
                break;
            }
            
            if (++ledCtrl.PauseDelayCnt >= 500)
            {
                ledCtrl.PauseDelayCnt = 0;
                LEDPinONOFF;
                
                if (LED_PIN)
                {
                    if (++ledCtrl.BlinkCnt >= ledCtrl.FaultLowBit)
                    {
                        LED_OFF;
                        ledCtrl.BlinkCnt = 0;
                        ledCtrl.ledState = LED_STATE_FAULT_CYCLE_GAP;
                    }
                }
            }
            
            break;
            
        // 整码间隔 3s
        case LED_STATE_FAULT_CYCLE_GAP:
            if (++ledCtrl.PauseDelayCnt >= 3000)
            {
                ledCtrl.PauseDelayCnt = 0;
                ledCtrl.ledState = LED_STATE_FAULT_HIGH_BLINK;
            }
            
            break;
            
        default:
            LED_OFF;
            ledCtrl.ledState = LED_STATE_OFF;
            break;
    }
}
