#include "RTE_CAN.h"
#include "CAN_Lib.h"
#include "CAN_APP.h"
#include "CAN_Communication_Matrix.h"
#include "Analog_Signals.h"
#include "RSCAN.h"
#include "Check_Ctrl.h"
#include "Display_Info.h"
#include "RTE_GPIO.h"
#include "TFT_LCD.h"

#define CAN_ID_1 0x781 //诊断ID
#define CAN_ID_2 0x521
#define CAN_ID_3 0x522

//外部软件诊断步骤
#define SW_OUT_READ_ORDER1 0xF1
#define SW_OUT_READ_ORDER2 0x95
//外部硬件诊断获取
#define HW_OUT_READ_ORDER1 0xF1
#define HW_OUT_READ_ORDER2 0x93
//内部软件诊断获取
#define SW_IN_READ_ORDER1 0x10
#define SW_IN_READ_ORDER2 0x24
//内部硬件版本号
#define HW_IN_READ_ORDER1 0x10
#define HW_IN_READ_ORDER2 0x24
//零件号号
#define PN_READ_ORDER1 0xF1
#define PN_READ_ORDER2 0x87
//软件释放时间
#define SWTIME_READ_ORDER1 0x10
#define SWTIME_READ_ORDER2 0x28

//零件号长度
#define PN_Length 20

CAN_Frame_st_t m_msg1;
CAN_Frame_st_t m_msg2;
CAN_Frame_st_t m_msg3;
CAN_Frame_st_t m_msg4;
CAN_Frame_st_t m_msg5;
CAN_Frame_st_t m_msg6;

uint8_t data1[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t data2[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t data3[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t data4[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t data5[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t data6[8] = {0, 0, 0, 0, 0, 0, 0, 0};

const unsigned char ForkDisplay[] = {24, 24,0X00,0X00,0X00,0X00,0X30,0X70,0XE0,0XC0,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X80,0XC0,0X70,0X30,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0X83,0XC7,0X66,0X38,0X38,0X7C,0XE6,0XC3,0X81,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0C,0X0C,0X06,0X03,0X01,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0X03,0X07,0X0E,0X0C,0X00,0X00,0X00,0X00,};

typedef enum {
    CAN_REG_FAIL = 0,  // 未注册/注册失败
    CAN_REG_OK         // 已注册成功
} CAN_Register_Result_e;

void Diagnostic_Init(void)
{
    SWOUTENable = 1;        //外部软件版本号功能
    HWOUTENable = 1;        //外部硬件版本号功能
    SWINENable = 1;         //软件内部版本号功能
    HWINENable = 0;         //硬件内部版本号功能
    PNENable = 1;           //零件号功能
    TIMEable = 1;           //程序释放时间
}

static CAN_Register_Result_e g_canRegStatus = CAN_REG_FAIL;  // 注册状态全局变量

void init_CAN_Frame(CAN_Frame_st_t* msg, uint32_t can_id, uint8_t can_len, uint8_t can_frame_ide, const uint8_t* data)
{
    for (uint32_t i = 0; i < can_len; i++) {
        msg->unCANData.u8CANData[i] = 0;
    }

    msg->u32CANID = can_id;
    msg->u8CANLEN = can_len;
    msg->u8CANFrameIDE = can_frame_ide;
    for (uint32_t i = 0; i < can_len; i++)
    {
        msg->unCANData.u8CANData[i] = data[i];
    }
}

void can_mid(CAN_Frame_st_t Msg)
{
    CAN_Frame_st_t m_msg;

    init_CAN_Frame(&m_msg, Msg.u32CANID, Msg.u8CANLEN, Msg.u8CANFrameIDE, Msg.unCANData.u8CANData);

    RSCAN0_CH4_Set_FIFO0_Data(&m_msg);
}

CAN_Register_Result_e checkIfRegistered(void)
{
    return g_canRegStatus;
}

void CAN_Service(void)
{
    init_CAN_Frame(&m_msg1, CAN_ID_1, 8, 0, data1);     //诊断
    init_CAN_Frame(&m_msg2, CAN_ID_2, 8, 0, data2);
    init_CAN_Frame(&m_msg3, CAN_ID_3, 8, 0, data3);
    // init_CAN_Frame(&m_msg4, CAN_ID_4, 8, 0, data4);
    // init_CAN_Frame(&m_msg5, CAN_ID_5, 8, 0, data5);
    // init_CAN_Frame(&m_msg6, CAN_ID_6, 8, 0, data6);

    can_mid(m_msg1);
    can_mid(m_msg2);
    can_mid(m_msg3);
    // can_mid(m_msg4);
    // can_mid(m_msg5);
    // can_mid(m_msg6);
}

void can_submit(void)
{
    switch (MENU_CHECK_STEP)
    {
        case  1:
            data2[1] = 0x00;        //水温

            data3[4] = 0x00;
            data3[5] = 0x00;
            break;
        case  2:
            data2[1] = 0x5A;

            data3[4] = 0xE8;
            data3[5] = 0x03;
            break;
        case  3:
            data2[1] = 0xAA;

            data3[4] = 0xE8;
            data3[5] = 0x03;
            break;
        case 4:
            data2[1] = 0xAA;

            data3[4] = 0xE8;
            data3[5] = 0x03;
            break;
        case 5:
            data2[1] = 0x00;

            data3[4] = 0x00;
            data3[5] = 0x00;
            break;
        case 6:
            data2[1] = 0x00;

            data3[4] = 0x00;
            data3[5] = 0x00;
            break;
        case 7:
            data2[1] = 0x00;

            data3[4] = 0x00;
            data3[5] = 0x00;
            break;
        case 8:
            data2[1] = 0x00;

            data3[4] = 0x00;
            data3[5] = 0x00;
            break;
        case 9:
            data2[1] = 0x00;

            data3[4] = 0x00;
            data3[5] = 0x00;
            break;
        case 10:
            data2[1] = 0x00;

            data3[4] = 0x00;
            data3[5] = 0x00;
            break;
        default:
            break;
    }
}
void UID_ADD(void)
{
    for(uint8_t i = 13; i > 1; i--)
    {
        if(UIDNumber2[i] < 9)
        {
            UIDNumber2[i] += 1;
            return;
        }
        else
        {
            UIDNumber2[i] = 0;
        }
    }
}
uint8_t SWOUTENable;
uint8_t HWOUTENable;
uint8_t SWINENable;
uint8_t HWINENable;
uint8_t PNENable;
uint8_t TIMEable;
uint8_t u8get714msg[8];
uint8_t u8getSWmsg[8];
uint8_t u8getUIDmsg[8];
uint8_t SWtestresult = 0;
uint8_t HWtestresult = 0;
uint8_t PNtestresult = 0;
uint8_t ruanjianbanbenhaoout[7];
uint8_t yingjianbanbenhaoout[7];
uint8_t ruanjianbanbenhaoin[8];
uint8_t yingjianbanbenhaoin[7];
uint8_t lingjianhao[25];
uint8_t shifang1shijian[9];
uint8_t UIDcode1[33];
uint8_t UIDcode2[33];
uint8_t zhenduanstep = 0;
extern uint32_t send0x714time;
uint8_t begin714 = 0;
uint8_t UIDdelay;
uint8_t SWINtestresult;

uint8_t ExternalSWStep;
uint8_t ExternalHWStep;
uint8_t InternalSWStep;
uint8_t InternalHWStep;
uint8_t PortNumberStep;
uint8_t SWTReleaseTimeStep;

//外部软件版本号
void MCU_SWversion(void)
{
    ExternalSWStep += MCU_SWversion_Get();

    switch(ExternalSWStep)
    {
        case 0:
        data1[0] = 0x03;
        data1[1] = 0x22;
        data1[2] = SW_OUT_READ_ORDER1;
        data1[3] = SW_OUT_READ_ORDER2;
        data1[4] = 0xAA;
        data1[5] = 0xAA;
        data1[6] = 0xAA;
        data1[7] = 0xAA;
        break;

        case 1:
        data1[0] = 0x30;
        data1[1] = 0x00;
        data1[2] = 0x00;
        data1[3] = 0xAA;
        data1[4] = 0xAA;
        data1[5] = 0xAA;
        data1[6] = 0xAA;
        data1[7] = 0xAA;
        break;

        default :
        memset(data1, 0x00, 8);
        break;
    }
}

//外部硬件版本号
void MCU_HWversion(void)
{
    ExternalHWStep += MCU_HWversion_Get();

    switch(ExternalHWStep)
    {
        case 0:
        data1[0] = 0x03;
        data1[1] = 0x22;
        data1[2] = HW_OUT_READ_ORDER1;
        data1[3] = HW_OUT_READ_ORDER2;
        data1[4] = 0xAA;
        data1[5] = 0xAA;
        data1[6] = 0xAA;
        data1[7] = 0xAA;
        break;

        case 1:
        data1[0] = 0x30;
        data1[1] = 0x00;
        data1[2] = 0x00;
        data1[3] = 0xAA;
        data1[4] = 0xAA;
        data1[5] = 0xAA;
        data1[6] = 0xAA;
        data1[7] = 0xAA;
        break;

        default :
        memset(data1, 0, 8);
        break;
    }
}

//软件内部版本号
void tyw_MCU_SWversion(void)
{
    InternalSWStep += tyw_MCU_SWversion_Get();

    switch(InternalSWStep)
    {
        case 0:
        data1[0] = 0x03;
        data1[1] = 0x22;
        data1[2] = SW_IN_READ_ORDER1;
        data1[3] = SW_IN_READ_ORDER2;
        data1[4] = 0xAA;
        data1[5] = 0xAA;
        data1[6] = 0xAA;
        data1[7] = 0xAA;
        break;

        case 1:
        data1[0] = 0x30;
        data1[1] = 0x00;
        data1[2] = 0x00;
        data1[3] = 0xAA;
        data1[4] = 0xAA;
        data1[5] = 0xAA;
        data1[6] = 0xAA;
        data1[7] = 0xAA;
        break;

        default :
        memset(data1, 0, 8);
        break;
    }
}

//硬件内部版本号
void tyw_MCU_HWversion(void)
{
    InternalHWStep += tyw_MCU_HWversion_Get();
    
    switch(InternalHWStep)
    {
        case 0:
        data1[0] = 0x03;
        data1[1] = 0x22;
        data1[2] = HW_IN_READ_ORDER1;
        data1[3] = HW_IN_READ_ORDER2;
        data1[4] = 0xAA;
        data1[5] = 0xAA;
        data1[6] = 0xAA;
        data1[7] = 0xAA;
        break;

        case 1:
        data1[0] = 0x30;
        data1[1] = 0x00;
        data1[2] = 0x00;
        data1[3] = 0xAA;
        data1[4] = 0xAA;
        data1[5] = 0xAA;
        data1[6] = 0xAA;
        data1[7] = 0xAA;
        break;

        default :
        memset(data1, 0, 8);
        break;
    }
}

void MCU_PartNumbers(void)
{    
    switch(PortNumberStep)
    {
        case 0:
        data1[0] = 0x03;
        data1[1] = 0x22;
        data1[2] = PN_READ_ORDER1;
        data1[3] = PN_READ_ORDER2;
        data1[4] = 0xAA;
        data1[5] = 0xAA;
        data1[6] = 0xAA;
        data1[7] = 0xAA;
        break;

        case 1:
        data1[0] = 0x30;
        data1[1] = 0x00;
        data1[2] = 0x00;
        data1[3] = 0xAA;
        data1[4] = 0xAA;
        data1[5] = 0xAA;
        data1[6] = 0xAA;
        data1[7] = 0xAA;
        break;

        default :
        memset(data1, 0, 8);
        break;
    }
}

void SW_Release_Time(void)
{    
    SWTReleaseTimeStep += SW_Release_Time_Get();

    switch(SWTReleaseTimeStep)
    {
        case 0:
        data1[0] = 0x03;
        data1[1] = 0x22;
        data1[2] = SWTIME_READ_ORDER1;
        data1[3] = SWTIME_READ_ORDER2;
        data1[4] = 0xAA;
        data1[5] = 0xAA;
        data1[6] = 0xAA;
        data1[7] = 0xAA;
        break;

        case 1:
        data1[0] = 0x30;
        data1[1] = 0x00;
        data1[2] = 0x00;
        data1[3] = 0xAA;
        data1[4] = 0xAA;
        data1[5] = 0xAA;
        data1[6] = 0xAA;
        data1[7] = 0xAA;
        break;

        default :
        memset(data1, 0, 8);
        break;
    }
}

uint8_t UDS_MMessage_Get[8] = {0};
void UDS_Message_Get(void)
{
    UDS_MMessage_Get[0] = Get_CAN_CH0_ID_UDS_byte0_Sig();
    UDS_MMessage_Get[1] = Get_CAN_CH0_ID_UDS_byte1_Sig();
    UDS_MMessage_Get[2] = Get_CAN_CH0_ID_UDS_byte2_Sig();
    UDS_MMessage_Get[3] = Get_CAN_CH0_ID_UDS_byte3_Sig();
    UDS_MMessage_Get[4] = Get_CAN_CH0_ID_UDS_byte4_Sig();
    UDS_MMessage_Get[5] = Get_CAN_CH0_ID_UDS_byte5_Sig();
    UDS_MMessage_Get[6] = Get_CAN_CH0_ID_UDS_byte6_Sig();
    UDS_MMessage_Get[7] = Get_CAN_CH0_ID_UDS_byte7_Sig();
}
uint8_t UDS_STEP;
//软件外部版本号获取
uint8_t MCU_SWversion_Get(void)
{
    uint8_t Result;
    Result = 0;
    if((UDS_MMessage_Get[0] == 0x10) && (UDS_MMessage_Get[1] == 0x09) &&\
    (UDS_MMessage_Get[3] == SW_OUT_READ_ORDER1) && (UDS_MMessage_Get[4] == SW_OUT_READ_ORDER2) && (ExternalSWStep == 0))
    {
        ruanjianbanbenhaoout[0] = UDS_MMessage_Get[5];
        ruanjianbanbenhaoout[1] = UDS_MMessage_Get[6];
        ruanjianbanbenhaoout[2] = UDS_MMessage_Get[7];
        Result = 1;
    }
    else if((UDS_MMessage_Get[0] == 0x21) && (ExternalSWStep == 1))
    {
        ruanjianbanbenhaoout[3] = UDS_MMessage_Get[1];
        ruanjianbanbenhaoout[4] = UDS_MMessage_Get[2];
        ruanjianbanbenhaoout[5] = UDS_MMessage_Get[3];
        ruanjianbanbenhaoout[6] = 0xFF;
        General_Number_Disp(ruanjianbanbenhaoout, 135, 25);
        UDS_STEP = HWOUT_READ;
    }

    return Result;
}

//硬件外部版本号获取
uint8_t MCU_HWversion_Get(void)
{
    uint8_t Result;
    Result = 0;
    if((UDS_MMessage_Get[0] == 0x10) && (UDS_MMessage_Get[1] == 0x09) &&\
    (UDS_MMessage_Get[3] == HW_OUT_READ_ORDER1) && (UDS_MMessage_Get[4] == HW_OUT_READ_ORDER2) && (ExternalHWStep == 0))
    {
        yingjianbanbenhaoout[0] = UDS_MMessage_Get[5];
        yingjianbanbenhaoout[1] = UDS_MMessage_Get[6];
        yingjianbanbenhaoout[2] = UDS_MMessage_Get[7];
        Result = 1;
    }
    else if((UDS_MMessage_Get[0] == 0x21) && (ExternalHWStep == 1))
    {
        yingjianbanbenhaoout[3] = UDS_MMessage_Get[1];
        yingjianbanbenhaoout[4] = UDS_MMessage_Get[2];
        yingjianbanbenhaoout[5] = UDS_MMessage_Get[3];
        yingjianbanbenhaoout[6] = 0xFF;
        General_Number_Disp(yingjianbanbenhaoout, 135, 50);
        UDS_STEP = SWIN_READ;
    }
    return Result;
}

//软件内部版本号获取
uint8_t tyw_MCU_SWversion_Get(void)
{
    uint8_t Result;
    Result = 0;
    if((UDS_MMessage_Get[3] == SW_IN_READ_ORDER1) && (UDS_MMessage_Get[4] == SW_IN_READ_ORDER2) && (InternalSWStep == 0))
    {
        ruanjianbanbenhaoin[0] = UDS_MMessage_Get[5];
        ruanjianbanbenhaoin[1] = UDS_MMessage_Get[6];
        ruanjianbanbenhaoin[2] = UDS_MMessage_Get[7];
        Result = 1;
    }
    else if((UDS_MMessage_Get[0] == 0x21) && (InternalSWStep == 1))
    {
        ruanjianbanbenhaoin[3] = UDS_MMessage_Get[1];
        ruanjianbanbenhaoin[4] = UDS_MMessage_Get[2];
        ruanjianbanbenhaoin[5] = UDS_MMessage_Get[3];
        if(UDS_MMessage_Get[4] == 0xAA)
        {
            ruanjianbanbenhaoin[6] = 0xFF;
        }
        else
        {
            ruanjianbanbenhaoin[6] = UDS_MMessage_Get[4];
            ruanjianbanbenhaoin[7] = 0xFF;
        }
        General_Number_Disp(ruanjianbanbenhaoin, 135, 75);
        UDS_STEP = HWIN_READ;
    }
    return Result;
}

//硬件内部版本号获取
uint8_t tyw_MCU_HWversion_Get(void)
{
    uint8_t Result;
    Result = 0;
    if((UDS_MMessage_Get[0] == 0x10) && (UDS_MMessage_Get[1] == 0x08) &&\
    (UDS_MMessage_Get[3] == HW_IN_READ_ORDER1) && (UDS_MMessage_Get[4] == HW_IN_READ_ORDER2) && (InternalHWStep ==0))
    {
        yingjianbanbenhaoin[0] = UDS_MMessage_Get[5];
        yingjianbanbenhaoin[1] = UDS_MMessage_Get[6];
        yingjianbanbenhaoin[2] = UDS_MMessage_Get[7];
        Result = 1;
    }
    else if((UDS_MMessage_Get[0] == 0x21) && (InternalHWStep == 1))
    {
        yingjianbanbenhaoin[3] = UDS_MMessage_Get[1];
        yingjianbanbenhaoin[4] = UDS_MMessage_Get[2];
        yingjianbanbenhaoin[5] = 0xFF;
        General_Number_Disp(yingjianbanbenhaoin, 135, 100);
        UDS_STEP = PN_READ;
    }
    return Result;
}

//零件号获取
uint8_t MCU_PartNumbers_Get(void)
{
    uint8_t Result;
    Result = 0;
    if((UDS_MMessage_Get[3] == PN_READ_ORDER1) && (UDS_MMessage_Get[4] == PN_READ_ORDER2) && (PortNumberStep == 0))
    {
        lingjianhao[0] = UDS_MMessage_Get[5];
        lingjianhao[1] = UDS_MMessage_Get[6];
        lingjianhao[2] = UDS_MMessage_Get[7];
        Result = 1;
    }
    else if((UDS_MMessage_Get[0] == 0x21) && (PortNumberStep == 1))
    {
        for(int i = 0; i < 7; i++)
        {
            if(UDS_MMessage_Get[i + 1] == 0xAA)
            {
                lingjianhao[PN_Length] = 0xFF;
                General_Number_Disp(lingjianhao, 135, 125);
                UDS_STEP = TIME_READ;
                break;
            }
            lingjianhao[i + 3] = UDS_MMessage_Get[i + 1];
        }

        if(PN_Length == 9)
        {
            lingjianhao[PN_Length] = 0xFF;
            General_Number_Disp(lingjianhao, 135, 125);
            UDS_STEP = TIME_READ;
        }
        else if(PN_Length > 9)
        {
            PortNumberStep = 2;
        }
        else
        {
            PortNumberStep = 0;
        }
    }
    else if((UDS_MMessage_Get[0] == 0x22) && (PortNumberStep == 2))
    {
        for(int i = 0; i < 7; i++)
        {
            if(UDS_MMessage_Get[i + 1] == 0xAA)
            {
                lingjianhao[PN_Length] = 0xFF;
                General_Number_Disp(lingjianhao, 135, 125);
                UDS_STEP = TIME_READ;
                break;
            }
            lingjianhao[i + 10] = UDS_MMessage_Get[i + 1];
        }

        if(PN_Length == 17)
        {
            lingjianhao[PN_Length] = 0xFF;
            General_Number_Disp(lingjianhao, 135, 125);
            UDS_STEP = TIME_READ;
        }
        else if(PN_Length > 17)
        {
            PortNumberStep = 3;
        }
        else
        {
            PortNumberStep = 0;
        }
    }
    else if((UDS_MMessage_Get[0] == 0x23) && (PortNumberStep == 3))
    {
        for(int i = 0; i < 7; i++)
        {
            if(UDS_MMessage_Get[i + 1] == 0xAA)
            {
                lingjianhao[PN_Length] = 0xFF;
                General_Number_Disp(lingjianhao, 68, 125);
                UDS_STEP = TIME_READ;
                break;
            }
            lingjianhao[i + 17] = UDS_MMessage_Get[i + 1];
        }

        if(PN_Length == 24)
        {
            lingjianhao[PN_Length] = 0xFF;
            General_Number_Disp(lingjianhao, 135, 125);
            UDS_STEP = TIME_READ;
        }
    }
    return Result;
}

//软件释放时间获取
uint8_t SW_Release_Time_Get(void)
{
    uint8_t Result;
    Result = 0;
    if((UDS_MMessage_Get[0] == 0x10) && (UDS_MMessage_Get[1] == 0x0B) &&\
    (UDS_MMessage_Get[3] == SWTIME_READ_ORDER1) && (UDS_MMessage_Get[4] == SWTIME_READ_ORDER2) && (SWTReleaseTimeStep ==0))
    {
        shifang1shijian[0] = UDS_MMessage_Get[5];
        shifang1shijian[1] = UDS_MMessage_Get[6];
        shifang1shijian[2] = UDS_MMessage_Get[7];
        Result = 1;
    }
    else if((UDS_MMessage_Get[0] == 0x21) && (SWTReleaseTimeStep == 1))
    {
        shifang1shijian[3] = UDS_MMessage_Get[1];
        shifang1shijian[4] = UDS_MMessage_Get[2];
        shifang1shijian[5] = UDS_MMessage_Get[3];
        shifang1shijian[6] = UDS_MMessage_Get[4];
        shifang1shijian[7] = UDS_MMessage_Get[5];
        shifang1shijian[8] = 0xFF;
        General_Number_Disp(shifang1shijian, 135, 175);
        UDS_STEP = Finish_READ;
    }
    return Result;
}

void SWOUTNotApplied(void)
{
    UDS_STEP++;
    TFT_LCD_Draw_Bmp(135, 25, ( uint8_t * )ForkDisplay);//显示×，不应用此功能
}
void HWOUTNotApplied(void)
{
    UDS_STEP++;
    TFT_LCD_Draw_Bmp(135, 50, ( uint8_t * )ForkDisplay);//显示×，不应用此功能
}
void SWINNotApplied(void)
{
    UDS_STEP++;
    TFT_LCD_Draw_Bmp(135, 75, ( uint8_t * )ForkDisplay);//显示×，不应用此功能
}
void HWINNotApplied(void)
{
    UDS_STEP++;
    TFT_LCD_Draw_Bmp(135, 100, ( uint8_t * )ForkDisplay);//显示×，不应用此功能
}
void PNNotApplied(void)
{
    UDS_STEP++;
    TFT_LCD_Draw_Bmp(68, 125, ( uint8_t * )ForkDisplay);//显示×，不应用此功能
}
void TIMENotApplied(void)
{
    UDS_STEP++;
    TFT_LCD_Draw_Bmp(135, 175, ( uint8_t * )ForkDisplay);//显示×，不应用此功能
}
uint8_t UDS_DisableFlag;
void UDS_Process_Service(void)
{
    switch(UDS_STEP)
    {
        case SWOUT_READ:
        if(SWOUTENable)
        {
            MCU_SWversion();
        }
        else
        {
            SWOUTNotApplied();
        }
        break;

        case HWOUT_READ:
        if(HWOUTENable)
        {
            MCU_HWversion();
        }
        else
        {
            HWOUTNotApplied();
        }
        break;

        case SWIN_READ:
        if(SWINENable)
        {
            tyw_MCU_SWversion();
        }
        else
        {
            SWINNotApplied();
        }
        break;

        case HWIN_READ:
        if(HWINENable)
        {
            tyw_MCU_HWversion();
        }
        else
        {
            HWINNotApplied();
        }
        break;

        case PN_READ:
        if(PNENable)
        {
            MCU_PartNumbers();
        }
        else
        {
            PNNotApplied();
        }
        break;

        case TIME_READ:
        if(TIMEable)
        {
            SW_Release_Time();
        }
        else
        {
            TIMENotApplied();
        }
        break;

        case Finish_READ:
        UDS_DisableFlag = 1;
        break;

        default :
        break;
    }
}




uint8_t readstep = 0;
void UIDRead(void)
{
    CAN_Frame_st_t m_msg9;
    uint8_t data9[8] = {0, 0, 0, 0, 0, 0, 0, 0};

    switch(readstep)
    {
        case 0:     //读取UID
        data9[0] = 0x03;
        data9[1] = 0x22;
        data9[2] = 0x50;
        data9[3] = 0x01;
        data9[4] = 0xAA;
        data9[5] = 0xAA;
        data9[6] = 0xAA;
        data9[7] = 0xAA;
        init_CAN_Frame(&m_msg9, 0x7A1, 8, 1, data9); 
        can_mid(m_msg9);
        readstep++;
        break;

        case 1:
        data9[0] = 0x30;
        data9[1] = 0x00;
        data9[2] = 0x00;
        data9[3] = 0xAA;
        data9[4] = 0xAA;
        data9[5] = 0xAA;
        data9[6] = 0xAA;
        data9[7] = 0xAA;
        init_CAN_Frame(&m_msg9, 0x7A1, 8, 1, data9); 
        can_mid(m_msg9);
        readstep++;
        break;

        default:
        readstep = 0;
        break;
    }
}
uint8_t UIDNumber[19] = {84,89,87,0,0,0,0,0,0,0,0,0,0,1,2,0,2,5,0xFF};
uint8_t UIDNumber2[15] = {0,5,2,2,0,0,0,0,0,0,0,0,0,0,0xFF};
uint8_t change = 13;
uint8_t writeflag = 0;
uint8_t UIDStep;
uint8_t seedresult[4] = {0};
void get_seed_msg(void);
uint8_t getseedresult = 0;
uint8_t waittime = 0;
void UIDWrite(void)
{
    CAN_Frame_st_t m_msg8;
    uint8_t data8[8] = {0, 0, 0, 0, 0, 0, 0, 0};

    if(UIDStep == 2)
    {
        waittime++;
        if(waittime > 3)
        {
            waittime = 0;
            UIDStep = 0;
        }
    }

    switch (UIDStep)
    {
        case 0:
            data8[0] = 0x02;
            data8[1] = 0x10;
            data8[2] = 0x03;
            data8[3] = 0xAA;
            data8[4] = 0xAA;
            data8[5] = 0xAA;
            data8[6] = 0xAA;
            data8[7] = 0xAA;
            init_CAN_Frame(&m_msg8, 0x7A1, 8, 1, data8); 
            can_mid(m_msg8);
            UIDStep++;
            break;
        case 1:
            data8[0] = 0x02;
            data8[1] = 0x27;
            data8[2] = 0x01;
            data8[3] = 0xAA;
            data8[4] = 0xAA;
            data8[5] = 0xAA;
            data8[6] = 0xAA;
            data8[7] = 0xAA;
            init_CAN_Frame(&m_msg8, 0x7A1, 8, 1, data8); 
            can_mid(m_msg8);
            UIDStep++;
            break;
        case 2:
            get_seed_msg();
            if(getseedresult == 1)
            {
                UIDStep++;
                getseedresult = 0;
            }
            break;
        case 3:
            waittime = 0;
            data8[0] = 0x06;
            data8[1] = 0x27;
            data8[2] = 0x02;
            data8[3] = seedresult[0];
            data8[4] = seedresult[1];
            data8[5] = seedresult[2];
            data8[6] = seedresult[3];
            data8[7] = 0xAA;
            init_CAN_Frame(&m_msg8, 0x7A1, 8, 1, data8); 
            can_mid(m_msg8);
            UIDStep++;
            break;
        case 4:
            data8[0] = 0x10;
            data8[1] = 0x23;
            data8[2] = 0x2E;
            data8[3] = 0x50;
            data8[4] = 0x01;
            data8[5] = 0x54;
            data8[6] = 0x59;
            data8[7] = 0x57;
            init_CAN_Frame(&m_msg8, 0x7A1, 8, 1, data8); 
            can_mid(m_msg8);
            UIDStep++;
            break;
        case 5:
            u8getUIDmsg[0] = Get_CAN_CH0_ID_7A9_byte0_Sig();
            u8getUIDmsg[1] = Get_CAN_CH0_ID_7A9_byte1_Sig();
            u8getUIDmsg[2] = Get_CAN_CH0_ID_7A9_byte2_Sig();
            u8getUIDmsg[3] = Get_CAN_CH0_ID_7A9_byte3_Sig();
            u8getUIDmsg[4] = Get_CAN_CH0_ID_7A9_byte4_Sig();
            u8getUIDmsg[5] = Get_CAN_CH0_ID_7A9_byte5_Sig();
            u8getUIDmsg[6] = Get_CAN_CH0_ID_7A9_byte6_Sig();
            u8getUIDmsg[7] = Get_CAN_CH0_ID_7A9_byte7_Sig();
            if((u8getUIDmsg[0] == 0x30) && (u8getUIDmsg[2] == 0x14))
            {
                data8[0] = 0x21;
                data8[1] = 0x30;
                data8[2] = 0x30;
                data8[3] = 0x30;
                data8[4] = 0x30;
                data8[5] = 0x30;
                data8[6] = 0x30;
                data8[7] = 0x30;
                init_CAN_Frame(&m_msg8, 0x7A1, 8, 1, data8); 
                can_mid(m_msg8);
            }
            else
            {
                UIDStep = 0;
                writeflag = 0;
            }
            UIDStep++;
            break;
        case 6:
            data8[0] = 0x22;
            data8[1] = 0x30;
            data8[2] = 0x30;
            data8[3] = 0x30;
            data8[4] = 0x31;
            data8[5] = 0x32;
            data8[6] = 0x30;
            data8[7] = 0x32;
            init_CAN_Frame(&m_msg8, 0x7A1, 8, 1, data8); 
            can_mid(m_msg8);
            UIDStep++;
            break;
        case 7:
            data8[0] = 0x23;
            data8[1] = 0x35;
            data8[2] = 0x30 + UIDNumber2[0];
            data8[3] = 0x30 + UIDNumber2[1];
            data8[4] = 0x30 + UIDNumber2[2];
            data8[5] = 0x30 + UIDNumber2[3];
            data8[6] = 0x30 + UIDNumber2[4];
            data8[7] = 0x30 + UIDNumber2[5];
            init_CAN_Frame(&m_msg8, 0x7A1, 8, 1, data8); 
            can_mid(m_msg8);
            UIDStep++;
            break;
        case 8:
            data8[0] = 0x24;
            data8[1] = 0x30 + UIDNumber2[6];
            data8[2] = 0x30 + UIDNumber2[7];
            data8[3] = 0x30 + UIDNumber2[8];
            data8[4] = 0x30 + UIDNumber2[9];
            data8[5] = 0x30 + UIDNumber2[10];
            data8[6] = 0x30 + UIDNumber2[11];
            data8[7] = 0x30 + UIDNumber2[12];
            init_CAN_Frame(&m_msg8, 0x7A1, 8, 1, data8); 
            can_mid(m_msg8);
            UIDStep++;
            break;
        case 9:
            data8[0] = 0x25;
            data8[1] = 0x30 + UIDNumber2[13];
            data8[2] = 0xAA;
            data8[3] = 0xAA;
            data8[4] = 0xAA;
            data8[5] = 0xAA;
            data8[6] = 0xAA;
            data8[7] = 0xAA;
            init_CAN_Frame(&m_msg8, 0x7A1, 8, 1, data8); 
            can_mid(m_msg8);
            UID_ADD();
            UIDStep++;
            break;
        default:
            writeflag = 0;
            UIDStep = 0;
            writebeing = 1;
            UIDresult = 0;
            break;
    }
}
void Get_ID_0x794_Msg(void)
{

}
uint8_t canlost;
uint8_t resettime = 0;
void uidreset(void)
{
    if(resettime > 50)
    {
        UIDresult = 0;
        resettime = 0;
        Display_TFT_Clear_UID2();
        canlost = 1;
    }
}
uint8_t writebeing = 1;
uint8_t UIDresult = 0;
uint8_t UIDcode1last[33];
void Get_UID_msg(void)
{
    u8get714msg[0] = Get_CAN_CH0_ID_7A9_byte0_Sig();
    u8get714msg[1] = Get_CAN_CH0_ID_7A9_byte1_Sig();
    u8get714msg[2] = Get_CAN_CH0_ID_7A9_byte2_Sig();
    u8get714msg[3] = Get_CAN_CH0_ID_7A9_byte3_Sig();
    u8get714msg[4] = Get_CAN_CH0_ID_7A9_byte4_Sig();
    u8get714msg[5] = Get_CAN_CH0_ID_7A9_byte5_Sig();
    u8get714msg[6] = Get_CAN_CH0_ID_7A9_byte6_Sig();
    u8get714msg[7] = Get_CAN_CH0_ID_7A9_byte7_Sig();
    if((u8get714msg[0] == 0x10) && (u8get714msg[4] == 0x01) && (UIDresult == 0))
    {
        // memset(UIDcode1,0xFF,sizeof(UIDcode1));
        // memcpy(UIDcode1,&u8get714msg[1],32);
        UIDcode1[0] = u8get714msg[5];
        UIDcode1[1] = u8get714msg[6];
        UIDcode1[2] = u8get714msg[7];
        UIDresult = 1;
    }
    if((u8get714msg[0] == 0x21) && (UIDresult == 1))
    {
       UIDcode1[3] = u8get714msg[1];
       UIDcode1[4] = u8get714msg[2];
       UIDcode1[5] = u8get714msg[3];
       UIDcode1[6] = u8get714msg[4];
       UIDcode1[7] = u8get714msg[5];
       UIDcode1[8] = u8get714msg[6];
       UIDcode1[9] = u8get714msg[7];
       UIDresult = 2;
    }
    else if((u8get714msg[0] == 0x22) && (UIDresult == 2))
    {
        UIDcode1[10] = u8get714msg[1];
        UIDcode1[11] = u8get714msg[2];
        UIDcode1[12] = u8get714msg[3];
        UIDcode1[13] = u8get714msg[4];
        UIDcode1[14] = u8get714msg[5];
        UIDcode1[15] = u8get714msg[6];
        UIDcode1[16] = u8get714msg[7];
        UIDresult = 3;
    }
    else if((u8get714msg[0] == 0x23) && (UIDresult == 3))
    {
        UIDcode1[17] = u8get714msg[1];
        UIDcode1[18] = u8get714msg[2];
        UIDcode1[19] = u8get714msg[3];
        UIDcode1[20] = u8get714msg[4];
        UIDcode1[21] = u8get714msg[5];
        UIDcode1[22] = u8get714msg[6];
        UIDcode1[23] = u8get714msg[7];
        UIDresult = 4;
    }
    else if((u8get714msg[0] == 0x24) && (UIDresult == 4))
    {
        UIDcode1[24] = u8get714msg[1];
        UIDcode1[25] = u8get714msg[2];
        UIDcode1[26] = u8get714msg[3];
        UIDcode1[27] = u8get714msg[4];
        UIDcode1[28] = u8get714msg[5];
        UIDcode1[29] = u8get714msg[6];
        UIDcode1[30] = u8get714msg[7];
        UIDresult = 5;
    }
    else if((u8get714msg[0] == 0x25) && (UIDresult == 5))
    {
        UIDcode1[31] = u8get714msg[1];
        UIDcode1[32] = 0xFF;
        UIDresult = 0;
        resettime = 0;

        if(canlost == 0)
        {
            for(int i = 0;i<33;i++)
            {
                if(UIDcode1last[i] != UIDcode1[i])
                {
                    General_Number_Disp(UIDcode1, 95, 225);
                    shouuid();
                }
            }
        }
        else
        {
            General_Number_Disp(UIDcode1, 95, 225);
            shouuid();
            canlost = 0;
        }

        for(int i = 0;i<33;i++)
        {
           UIDcode1last[i] = UIDcode1[i];
        }
    }
}


uint32_t ValidSeedKey;
uint32_t GenerateKey(uint8_t *Seed)
{
    // const uint8_t Xor[4] = {0xAC, 0x89, 0x18, 0xF2};
    // uint8_t key_array[4], Cal[4];
    // uint32_t key_value;

    // for (size_t i = 0; i < 4; i++)
    // {
    //     Cal[i] = Seed[i] ^ Xor[i];
    // }

    // key_array[0] = ((Cal[2] & 0xF0) << 4) | (Cal[3] & 0xF0);
    // key_array[1] = ((Cal[3] & 0x2F) << 2) | (Cal[1] & 0x03);
    // key_array[2] = ((Cal[1] & 0xFC) >> 2) | (Cal[0] & 0xC0);
    // key_array[3] = ((Cal[0] & 0x0F) << 4) | (Cal[2] & 0x0F);

    // key_value = ((uint32_t)key_array[0] << 24U);
    // key_value = key_value | ((uint32_t)key_array[1] << 16U);
    // key_value = key_value | ((uint32_t)key_array[2] << 8U);
    // key_value = key_value | (uint32_t)key_array[3];

    // return (key_value);


    unsigned char i = 0u;
	unsigned char T1[4u] = { 0u };
	unsigned char T2[4u] = { 0u };
	unsigned char Xor[4u] = { 0u };
    unsigned char arr[4u] = { 0u };
	unsigned char KeyConst[4u] = { 0u };
	unsigned char KeyConst_L1[4u] = { 0xACu, 0x89u, 0x18u, 0xF2u };
    unsigned char iSeedArray[4u] = { 0u };
    for (i = 0u; i < 4u; i++)
	{
        iSeedArray[i] = Seed[i];
    }

	Xor[0u] = iSeedArray[2u];
	Xor[1u] = iSeedArray[3u];
	Xor[2u] = iSeedArray[0u];
	Xor[3u] = iSeedArray[1u];

	for (i = 0u; i < 4u; i++)
	{
		KeyConst[i] = KeyConst_L1[i];
	}

	for (i = 0u; i < 4u; i++)
	{
		T1[i] = iSeedArray[i] ^ KeyConst[i];
		T2[i] = Xor[i] ^ KeyConst[i];
		arr[i] = (T1[i] + T2[i]) & 0xFFu;
	}
    ValidSeedKey = ((uint32_t)arr[0u] <<24u) + ((uint32_t)arr[1u] << 16u) + ((uint32_t)arr[2u] << 8u) + ((uint32_t)arr[3u] );
    return ValidSeedKey;
}

// void CalculateKey(void)
// {
//     unsigned char i = 0u;
//     unsigned char T1[4u] = { 0u };
//     unsigned char T2[4u] = { 0u };
//     unsigned char Xor[4u] = { 0u };
//     unsigned char arr[4u] = { 0u };
//     unsigned char KeyConst[4u] = { 0u };
//     unsigned char KeyConst_L1[4u] = { 0xACu, 0x89u, 0x18u, 0xF2u };
//     unsigned char iSeedArray[4u] = { 0u };
//     for (i = 0u; i < 4u; i++)
//     {
//         iSeedArray[i] = Seed[i];
//     }

//     Xor[0u] = iSeedArray[2u];
//     Xor[1u] = iSeedArray[3u];
//     Xor[2u] = iSeedArray[0u];
//     Xor[3u] = iSeedArray[1u];

//     for (i = 0u; i < 4u; i++)
//     {
//         KeyConst[i] = KeyConst_L1[i];
//     }

//     for (i = 0u; i < 4u; i++)
//     {
//         T1[i] = iSeedArray[i] ^ KeyConst[i];
//         T2[i] = Xor[i] ^ KeyConst[i];
//         arr[i] = (T1[i] + T2[i]) & 0xFFu;
//     }
//     ValidSeedKey = ((uint32_t)arr[0u] <<24u) + ((uint32_t)arr[1u] << 16u) + ((uint32_t)arr[2u] << 8u) + ((uint32_t)arr[3u] );
//    
// }
uint8_t seednum[4] = {0};
uint8_t fuelreset1 = 0;
uint8_t fuelreset2 = 0;
uint8_t fuelreset3 = 0;
uint8_t fuelreset4 = 0;
uint32_t testseed;
void get_seed_msg(void)
{
    if(getseedresult == 1)
    {
        return ;
    }
    u8get714msg[0] = Get_CAN_CH0_ID_7A9_byte0_Sig();
    u8get714msg[1] = Get_CAN_CH0_ID_7A9_byte1_Sig();
    u8get714msg[2] = Get_CAN_CH0_ID_7A9_byte2_Sig();
    u8get714msg[3] = Get_CAN_CH0_ID_7A9_byte3_Sig();
    u8get714msg[4] = Get_CAN_CH0_ID_7A9_byte4_Sig();
    u8get714msg[5] = Get_CAN_CH0_ID_7A9_byte5_Sig();
    u8get714msg[6] = Get_CAN_CH0_ID_7A9_byte6_Sig();
    u8get714msg[7] = Get_CAN_CH0_ID_7A9_byte7_Sig();
    if(u8get714msg[1] == 0x67 && u8get714msg[2] == 0x01)
    {
        memcpy(seednum,&u8get714msg[3],4);
        testseed = GenerateKey(seednum);
        seedresult[0] = (uint8_t)(testseed >> 24);
        seedresult[1] = (uint8_t)(testseed >> 16);
        seedresult[2] = (uint8_t)(testseed >> 8);
        seedresult[3] = (uint8_t)testseed ;
        getseedresult = 1;
        
    }
    // getseedresult = 1;
}