

#include "common_include.h"
#include "s6j3360_LCDB.h"

/*****************************************************************************/
/* Local pre-processor symbols/macros ('#define')                            */
/*****************************************************************************/
//#define     WRITE(r,v) r=v
//#define     READ(r) r

volatile  uint8_t     UP_VSYNC;
volatile  uint32_t    UpScreenTime;
volatile  uint8_t     UpScreenStep;
volatile  uint8_t     LcdBusState;

extern void bsp_HDOG_Feed(void);
/*
#define gImage_111 0x04000000 + (uint32_t)_Bottom_Theme1_Pointer02_X291_Y26_R
const unsigned char _Bottom_Theme1_Pointer02_X291_Y26_R[16] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
};
*/
/*
unsigned char gImage0[] = { //0X22,0X01,
0X0A,0X00,0X10,0X00, 
0X0F,0X03,0XF1,0XF8,0XFC,0XFC,0XFC,0XF1,0X03,0X0F,0XF0,0XC0,0X8F,0X1F,0X3F,0X3F,
0X3F,0X8F,0XC0,0XF0,};

unsigned char gImage_1[] = { // 0X22,0X01,
0X0A,0X00,0X10,0X00, 
0XF9,0XF9,0XF9,0XFC,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X3F,0X3F,0X3F,0X3F,0X00,0X00,
0X3F,0X3F,0X3F,0X3F,};

*/

#define     WPREG_PPC(n,d)                          \
{                                                   \
    un_ppc_keycdr_t wk;                             \
    unsigned long adr = (unsigned long)&n;          \
    unsigned char size_key;                         \
    wk.au16Halfword[0] = adr & 0x7FFF;              \
    size_key = (sizeof(n) >> 1) << 4;               \
    wk.au8Byte[3] = size_key | (0 << 6);            \
    PPC_KEYCDR = wk.u32Register;                    \
    wk.au8Byte[3] = size_key | (1 << 6);            \
    PPC_KEYCDR = wk.u32Register;                    \
    wk.au8Byte[3] = size_key | (2 << 6);            \
    PPC_KEYCDR = wk.u32Register;                    \
    wk.au8Byte[3] = size_key | (3 << 6);            \
    PPC_KEYCDR = wk.u32Register;                    \
    n = d;                                          \
}

/*-------------------------------------------------------------------------
* Function Name  : VsyncDetectCallback
* Description    :
* Input          : None
* Output         : None
* Return         : None
* onther         :
*
--------------------------------------------------------------------------*/
static void VsyncDetectCallBack(uint8_t channel)
{
    uint8_t   sw = 0;

    if((UpScreenStep) && (UpScreenTime > 1000))
    {
        LCDPanelUpdtCtrl.Request = 0;
        UpScreenStep = 0;
        UP_VSYNC = 0;
        LcdBusState = 1;
    }
    else
    {
        sw = (memoryVramSel + 1) % 2;
        if((g_DrawInfo.VramCalOverFlag[ sw ]) && (UP_VSYNC == 0))
        {         
             LCDPanelGraphicRAM = (uint32_t*)VRAM_BUF[ sw ];
             memoryVramSel = sw;
             UP_VSYNC = 1;
             LCD_Panel_Update_Req(96,128);
             UpScreenStep = 1;
             UpScreenTime = 0;
        }
    }
}

/*-------------------------------------------------------------------------
* Function Name  : LcdBus_Check
* Description    :
* Input          : None
* Output         : None
* Return         : None
* onther         :
*
--------------------------------------------------------------------------*/
void LcdBus_Check(void)
{
    if(LcdBusState)
    {
         LCD_BUS_Init();
    }
}

/*-------------------------------------------------------------------------
* Function Name  : LcdBus_InstrFifo_isr
* Description    :
* Input          : None
* Output         : None
* Return         : None
* onther         :
*
--------------------------------------------------------------------------*/
__irq __arm  void LcdBus_InstrFifo_isr(void)
{
    if((UpScreenStep) && (LcdBusState == 0))
    {
         LCD_Panel_Update_ISR(UpScreenStep);
    }
        
    LCDB_InterruptClear = 0x04;
    IRC0_IRQHC = INTERRUPTS_IRQ_NUMBER_86;
}

/*-------------------------------------------------------------------------
* Function Name  : VsyncDetectionInit
* Description    : 初始化外部中断 为了VSYNC同步
* Input          :
* Output         : None
* Return         : None
* onther         : WindowY:page Number
--------------------------------------------------------------------------*/
void VsyncDetectionInit(void)
{
    stc_port_pin_config_t stc_port_pin_config0_12= { .enOutputFunction      = PortOutputResourceGPIO,
        .enOutputDrive         = PortOutputDriveA,
        .enPullResistor        = PortPullResistorNone,
        .enInputLevel          = PortInputLevelCmosA,
        .bInputEnable          = TRUE,
        .bNoiseFilterEnable    = FALSE,
        .enGpioDirection       = PortGpioInput,
    .enGpioInitOutputLevel = PortGpioLow};
    Port_SetPinConfig( 0, 12, &stc_port_pin_config0_12 );
    
    stc_eic_config_t      stcEicConfig;
    // EIC Configuration
    stcEicConfig.enRequestEvent               = EicFallingEdge;          // Detect rising edge
    stcEicConfig.bInputNoiseFilterEnable      = TRUE;                   // Enable the noise filter
    stcEicConfig.bDmaRequestEnable            = FALSE;                  // Disable the DMA request
    stcEicConfig.pfnCallback                  = &VsyncDetectCallBack;   // using interrupts
    
    Port_SelectInputPort( &RIC.unRESIN274, PortInputPortC );
    
    Eic_Init((stc_eic00_t *) &EIC00, 23, &stcEicConfig);
    
    Eic_Enable((stc_eic00_t *) &EIC00, 23);
    
    Port_EnableInput();
}

void LCD_BUS_Init(void)
{
    un_lcdb_interfaceconfig_t                     interfaceCofigTemp      = { 0 };
    un_lcdb_writetimingconfig_t                   writeTimingCofigTemp    = { 0 };
    un_lcdb_readtimingconfig_t                    readTimingCofigTemp     = { 0 };
    un_lcdb_commandtransfermapping0_t             cmdTransMap0CofigTemp   = { 0 };
    un_lcdb_datatransfermapping0_t                dataTransMap0CofigTemp  = { 0 };
    un_lcdb_datatransfermapping1_t                dataTransMap1CofigTemp  = { 0 };
    un_lcdb_colorcomponentbits_t                  colorComponentBitsTemp  = { 0 };
    un_lcdb_colorcomponentshift_t                 colorComponentShiftTemp = { 0 };
    un_lcdb_destinationattributes_t               destAttributesTemp      = { 0 };
    un_lcdb_instructionfifoconfig_t               instructionfifoconfigTemp = { 0 };
    un_lcdb_interruptenable_t                     interruptenableTemp = { 0 };
    
    LcdBusState = 0;
    memoryVramSel = 0;
    
    //端口配置
    WPREG_PPC(PPC_PCFGR215, 0x1002);  // LCDD0  pin127
    WPREG_PPC(PPC_PCFGR216, 0x1002);  // LCDD1  pin128
    WPREG_PPC(PPC_PCFGR217, 0x1002);  // LCDD2  pin129
    WPREG_PPC(PPC_PCFGR218, 0x1002);  // LCDD3  pin130
    WPREG_PPC(PPC_PCFGR222, 0x1002);  // LCDD4  pin136
    WPREG_PPC(PPC_PCFGR223, 0x1002);  // LCDD5  pin137
    WPREG_PPC(PPC_PCFGR224, 0x1002);  // LCDD6  pin138
    WPREG_PPC(PPC_PCFGR225, 0x1002);  // LCDD7  pin139
    
    WPREG_PPC(PPC_PCFGR006, 0x1002);  // CS#    pin008
    WPREG_PPC(PPC_PCFGR007, 0x1002);  // WR#    pin011
    WPREG_PPC(PPC_PCFGR008, 0x1002);  // RD#    pin012
    WPREG_PPC(PPC_PCFGR010, 0x1002);  // RS     pin014
    WPREG_PPC(PPC_PCFGR011, 0x1002);  // RES#   pin015
    VsyncDetectionInit();//WPREG_PPC(PPC_PCFGR012, 0x1002);  // TE     pin016
    
    
    //总线配置
    //Interface Config
    LCDB_LockUnlockLcd = 0x691DB936;
    interfaceCofigTemp.stcField.u2InterfaceType       = 0;      // 0: INTEL80_TYPE1
    interfaceCofigTemp.stcField.u2InterfaceWidth      = 0;      // 0: 8bit LCDBus
    interfaceCofigTemp.stcField.u1CsPolarity          = 0;      // CS is low active
    interfaceCofigTemp.stcField.u1WrPolarity          = 0;      // WR# is default protocol
    interfaceCofigTemp.stcField.u1RdPolarity          = 0;      // RD# is default protocol
    interfaceCofigTemp.stcField.u1RsPolarity          = 0;      // RS is low signal level
    interfaceCofigTemp.stcField.u1DataPolarity        = 0;      // Data bus is used
    interfaceCofigTemp.stcField.u1TePolarity          = 0;      // TE is high active
    LCDB_InterfaceConfig = interfaceCofigTemp.u32Register;
    
    //Write Timing Config
    LCDB_LockUnlockLcd = 0x691DB936;
    writeTimingCofigTemp.u32Register                  = LCDB_WriteTimingConfig;
    writeTimingCofigTemp.stcField.u8WriteSetupCycles  = 1;
    writeTimingCofigTemp.stcField.u8WriteActiveCycles = 3;
    writeTimingCofigTemp.stcField.u8WriteHoldCycles   = 1;
    LCDB_WriteTimingConfig = writeTimingCofigTemp.u32Register;
    
    //Read Timing Config (addr: 0x0014)
    LCDB_LockUnlockLcd = 0x691DB936;
    readTimingCofigTemp.u32Register                   = LCDB_ReadTimingConfig;
    readTimingCofigTemp.stcField.u8ReadSetupCycles    = 2;
    readTimingCofigTemp.stcField.u8ReadActiveCycles   = 5;
    readTimingCofigTemp.stcField.u8ReadHoldCycles     = 2;
    LCDB_ReadTimingConfig = readTimingCofigTemp.u32Register;
    
    //Command Transfer Mapping 0
    LCDB_LockUnlockLcd = 0x691DB936;
    cmdTransMap0CofigTemp.stcField.u5CommandTransfer0Bits   = 8;    // sbits
    cmdTransMap0CofigTemp.stcField.u5CommandTransfer0SrcLsb = 0;    // slsb
    cmdTransMap0CofigTemp.stcField.u5CommandTransfer0DstLsb = 0;    // dlsb
    cmdTransMap0CofigTemp.stcField.u1CommandTransfer0Next   = 0;    // next
    LCDB_CommandTransferMapping0 = cmdTransMap0CofigTemp.u32Register;
    
    //Data Transfer Mapping 0
    LCDB_LockUnlockLcd = 0x691DB936;
    dataTransMap0CofigTemp.stcField.u5DataTransfer0Bits   = 8;      // sbits
    dataTransMap0CofigTemp.stcField.u5DataTransfer0SrcLsb = 0;      // slsb
    dataTransMap0CofigTemp.stcField.u5DataTransfer0DstLsb = 0;      // dlsb
    dataTransMap0CofigTemp.stcField.u1DataTransfer0Next   = 0;      // next
    LCDB_DataTransferMapping0 = dataTransMap0CofigTemp.u32Register;
    
    //ColorComponentBits
    LCDB_LockUnlockLcd = 0x691DB936;
    colorComponentBitsTemp.stcField.u4ComponentBitsBlue  = 0;
    colorComponentBitsTemp.stcField.u4ComponentBitsGreen = 4;
    colorComponentBitsTemp.stcField.u4ComponentBitsRed   = 0;
    LCDB_ColorComponentBits = colorComponentBitsTemp.u32Register;
    
    //ColorComponentShift
    LCDB_LockUnlockLcd = 0x691DB936;
    colorComponentShiftTemp.stcField.u5ComponentShiftBlue  = 0;
    colorComponentShiftTemp.stcField.u5ComponentShiftGreen = 0;
    colorComponentShiftTemp.stcField.u5ComponentShiftRed   = 0;
    LCDB_ColorComponentShift = colorComponentShiftTemp.u32Register;
    
    //DestinationAttributes
    LCDB_LockUnlockLcd = 0x691DB936;
    destAttributesTemp.stcField.u5BitsPerTransfer = 8;
    destAttributesTemp.stcField.u5BitsPerPixel    = 4;
    LCDB_DestinationAttributes = destAttributesTemp.u32Register;
    
    //reset and clear the content of command fifo
    LCDB_LockUnlockLcd = 0x691DB936;
    LCDB_SoftwareReset = 1;
    
    //clear the content of rxfifo
    LCDB_LockUnlockLcd = 0x691DB936;
    LCDB_RxFifoControl = 1;
    
#if 1
    LCDB_LockUnlockLcd = 0x691DB936;
    instructionfifoconfigTemp.stcField.u6InstrThresholdLow = 0;     //下限是 0
    instructionfifoconfigTemp.stcField.u6InstrThresholdHigh = 1;
    instructionfifoconfigTemp.stcField.u2InstrThresholdTrigger = 0;  //0 = LOW
    LCDB_InstructionFifoConfig = instructionfifoconfigTemp.u32Register;

    LCDB_LockUnlockLcd = 0x691DB936;
    interruptenableTemp.stcField.u1InstrFifoInterruptEnable = 1;
    LCDB_InterruptEnable = interruptenableTemp.u32Register;
#endif
}



void LCD_BUS_Panel_Reset_Ctrl(uint8_t Level)
{
    uint16_t cnt = 0;
    while (LCD_BUS_Get_Status())
    {
        cnt ++;
        if(cnt > 60000)
        {
            break;
        }
    }
    
    if(Level)
    {
        LCD_BUS_Write_Bus_Cmd(LCD_BUS_CMD_SET_RESET, 1);
    }
    else
    {
        LCD_BUS_Write_Bus_Cmd(LCD_BUS_CMD_SET_RESET, 0);
    }
    LCD_BUS_Write_Bus_Cmd(LCD_BUS_CMD_NOP, 16);
}


void LCD_BUS_Write_Cmd(uint8_t Cmd, uint8_t *pPara, uint8_t ParaLen)
{
    uint16_t i = 0;
    
    if ((ParaLen) && (pPara == NULL))
        return;
    
    while (LCD_BUS_Get_Status())
    {
        i ++;
        if(i > 800)
        {
            break;
        }
    }

    LCD_BUS_Write_Bus_Cmd(LCD_BUS_CMD_IR_SET, Cmd);
    
    if(ParaLen)
    {   
        for(i = 0; i < ParaLen; i++)
        {
            LCD_BUS_Write_Bus_Cmd(LCD_BUS_CMD_DR_SET, pPara[ i ]);
        }
    }
}

uint8_t LCD_BUS_Get_Status(void)
{
    if ((LCDB_InstrFifoStatus_InstrEmpty == 0) && (LCDB_SequencerStatus_LcdInterfaceState == 0))
        return 1;
    
    return 0;
}

void LCD_BUS_Write_Bus_Cmd(uint32_t Opcode, uint8_t Para)
{
    if(LCDB_InstrFifoStatus_InstrFull)
    {
        NOP();NOP();NOP();NOP();NOP();
    }
    if (LCDB_InstrFifoStatus_InstrFull == 0)
    {
        LCDB_InstructionFifo0 = (Opcode + Para);
    }
}

void LCD_BUS_Write_Bus_Fifo(uint32_t Data)
{
    if(LCDB_InstrFifoStatus_InstrFull)
    {
        NOP();NOP();NOP();NOP();NOP();
    }
    if (LCDB_InstrFifoStatus_InstrFull == 0)
    {
        LCDB_InstructionFifo0 = Data;
    }
}    
#define CHECK_BENCH_SQFL_ICV 0
#define CHECK_BENCH_SQFL_EV 1    
#define CUR_CHECK_BENCH_TYPE CHECK_BENCH_SQFL_ICV

//SQFL    
#define SQFL_ICV_PART_NUM1 "94023J1000"
#define SQFL_ICV_PART_NUM2 "94023J1010"
#define SQFL_ICV_PART_NUM3 "94023J1020"
#define SQFL_ICV_PART_NUM4 "94023J1030"
#define SQFL_EV_PART_NUM1  "94023AZ000"  


#define BDC_PE_SVC_PART_NUM  "94033Q8000"  
#define BDC_PE_STD_PART_NUM  "94023Q8000" 


#define DL3C_SVC_PART_NUM "94013L6000"
#define DL3C_STD_PART_NUM "94003L6000"

//void UpdataCenterDisp(void)
//{
//    if ((g_DrawInfo.VramCalOverFlag[ 0 ] == 0) || (g_DrawInfo.VramCalOverFlag[ 1 ] == 0))
//    {
//        if(g_DrawInfo.VramCalOverFlag[ 0 ] == 0)
//        {
//            g_DrawInfo.VramSelectBuf = 0;
//        }
//        if(g_DrawInfo.VramCalOverFlag[ 1 ] == 0)
//        {
//            g_DrawInfo.VramSelectBuf = 1;
//        }
//        if(g_DrawInfo.VramSelectBuf > 1)
//        {
//            g_DrawInfo.VramSelectBuf = 0;
//        }
//        Api_ClearAllVram(g_DrawInfo.VramSelectBuf,0xffffffff);
//        
//        UpdateCenterTripC();
//       
//        g_DrawInfo.VramCalOverFlag[ g_DrawInfo.VramSelectBuf ] = 1;
//    }
//}
extern uint8_t CluPartNum[16];
extern uint8_t GetPartNumFinish;
extern uint8_t CheckClusterValid;
extern uint8_t Button_Value;
extern uint8_t Button_Press;
uint16_t CheckOkTimerCnts = 0;
void UpdataCenterDisp(uint8_t n)
{
    if ((g_DrawInfo.VramCalOverFlag[ 0 ] == 0) || (g_DrawInfo.VramCalOverFlag[ 1 ] == 0))
    {
        if(g_DrawInfo.VramCalOverFlag[ 0 ] == 0)
        {
            g_DrawInfo.VramSelectBuf = 0;
        }
        if(g_DrawInfo.VramCalOverFlag[ 1 ] == 0)
        {
            g_DrawInfo.VramSelectBuf = 1;
        }
        if(g_DrawInfo.VramSelectBuf > 1)
        {
            g_DrawInfo.VramSelectBuf = 0;
        }
        Api_ClearAllVram(g_DrawInfo.VramSelectBuf,0xffffffff);
        
        if (n == 0) {
            UpdateCenterTripC();
        } else {
            if (CoverPageTimerCnts) {
                //UpdateCoverPage();
            } else {  
                if (ClusterValidTimerCnts == 0) {
                    memset(CluPartNum, 0, sizeof (CluPartNum));
                    GetPartNumFinish = 0;
                    UpdateConnectCluster();
                } else {
                    uint8_t tmp = 0;
                    
                    GetPartNum();   
                    if (GetPartNumFinish == 1) {
//#if (CUR_CHECK_BENCH_TYPE == CHECK_BENCH_GL3_ICV)
//                        tmp = ((memcmp(CluPartNum, GL3_ICV_ER_PART_NUM, 10) == 0u) || (memcmp(CluPartNum, GL3_ICV_NER_PART_NUM, 10) == 0u));
//#endif
//#if (CUR_CHECK_BENCH_TYPE == CHECK_BENCH_GL3_HEV)
//                        tmp = (memcmp(CluPartNum, GL3_HEV_PART_NUM, 10) == 0u);
//#endif
//#if (CUR_CHECK_BENCH_TYPE == CHECK_BENCH_US4_ICV)
//                        tmp = ((memcmp(CluPartNum, US4_ICV_ER_PART_NUM, 10) == 0u) || (memcmp(CluPartNum, US4_ICV_NER_PART_NUM, 10) == 0u));
//#endif
                        
//#if (CUR_CHECK_BENCH_TYPE == CHECK_BENCH_SG2_PHEV)
//                        tmp = ((memcmp(CluPartNum, SG2_PHEV_PART_NUM1, 10) == 0u) || (memcmp(CluPartNum, SG2_PHEV_PART_NUM2, 10) == 0u) ||   
//                            (memcmp(CluPartNum, SG2_PHEV_PART_NUM3, 10) == 0u) || (memcmp(CluPartNum, SG2_PHEV_PART_NUM4, 10) == 0u) ||   
//                                (memcmp(CluPartNum, SG2_PHEV_PART_NUM5, 10) == 0u) || (memcmp(CluPartNum, SG2_PHEV_PART_NUM6, 10) == 0u) ||   
//                                    (memcmp(CluPartNum, SG2_PHEV_PART_NUM7, 10) == 0u) || (memcmp(CluPartNum, SG2_PHEV_PART_NUM8, 10) == 0u) ||   
//                                        (memcmp(CluPartNum, SG2_PHEV_PART_NUM9, 10) == 0u) || (memcmp(CluPartNum, SG2_PHEV_PART_NUM10, 10) == 0u) ||   
//                                            (memcmp(CluPartNum, SG2_PHEV_PART_NUM11, 10) == 0u) || (memcmp(CluPartNum, SG2_PHEV_PART_NUM12, 10) == 0u) ||   
//                                                (memcmp(CluPartNum, SG2_PHEV_PART_NUM13, 10) == 0u) || (memcmp(CluPartNum, SG2_PHEV_PART_NUM14, 10) == 0u) ||   
//                                                    (memcmp(CluPartNum, SG2_PHEV_PART_NUM15, 10) == 0u) || (memcmp(CluPartNum, SG2_PHEV_PART_NUM16, 10) == 0u)
//                                                        );
//#endif.
                        
if (CUR_CHECK_BENCH_TYPE == CHECK_BENCH_SQFL_ICV)
                      tmp = ( (memcmp(CluPartNum, BDC_PE_STD_PART_NUM, 10) == 0u) || (memcmp(CluPartNum, BDC_PE_SVC_PART_NUM, 10) == 0u));
//#endif
                        tmp= 1;
                        if (tmp != 0u) {
                            //                            UpdateClusterCheck();
                            //                            GET_BUTTON_AUTO_LEVEL;
                            //                            if(BUTTON_AUTO_IN == 0){
                            //                                if (CheckOkTimerCnts < 500) {
                            //                                    CheckOkTimerCnts++;
                            //                                }
                            //                                if (CheckOkTimerCnts >= 100) {
                            //                                    CheckClusterValid = 1;
                            //                                    Button_Value = 16;//yrf++
                            //                                    Button_Press= 1;//yrf++
                            //                                    g_Stage = 0;
                            //                                }
                            //                            } else {
                            //                                CheckOkTimerCnts = 0;
                            //                            }
                            
                            CheckClusterValid = 1;
                            Button_Value = 16;//yrf++
                            Button_Press= 1;//yrf++
                            g_Stage = 0;
                            
                        } else {
                            UpdateClusterError();//显示
                        }
                    }
                }
            }
        }
        
        g_DrawInfo.VramCalOverFlag[ g_DrawInfo.VramSelectBuf ] = 1;
    }
} 
    



