/******************************************************************************
*****************************************************************************/
/* __DISCLAIMER_START__                                                      */
/******************************************************************************
* (c) 2014-2017, Cypress Semiconductor Corporation
* or a subsidiary of Cypress Semiconductor Corporation. All rights
* reserved.
*
* This software, including source code, documentation and related
* materials ("Software"), is owned by Cypress Semiconductor
* Corporation or one of its subsidiaries ("Cypress") and is protected by
* and subject to worldwide patent protection (United States and foreign),
* United States copyright laws and international treaty provisions.
* Therefore, you may use this Software only as provided in the license
* agreement accompanying the software package from which you
* obtained this Software ("EULA").
*
* If no EULA applies, Cypress hereby grants you a personal, nonexclusive,
* non-transferable license to copy, modify, and compile the
* Software source code solely for use in connection with Cypress's
* integrated circuit products. Any reproduction, modification, translation,
* compilation, or representation of this Software except as specified
* above is prohibited without the express written permission of Cypress.
*
* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO
* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING,
* BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. Cypress reserves the right to make
* changes to the Software without notice. Cypress does not assume any
* liability arising out of the application or use of the Software or any
* product or circuit described in the Software. Cypress does not
* authorize its products for use in any products where a malfunction or
* failure of the Cypress product may reasonably be expected to result in
* significant property damage, injury or death ("High Risk Product"). By
* including Cypress's product in a High Risk Product, the manufacturer
* of such system or application assumes all risk of such use and in doing
* so agrees to indemnify Cypress against all liability.
******************************************************************************/
/* __DISCLAIMER_END__                                                        */
/*****************************************************************************
** \file hsspi_flash_setting.c
**
** HSSPI Flash setting code.
**
*****************************************************************************/

/*****************************************************************************/
/* Include files                                                             */
/*****************************************************************************/
#include "common_include.h"
#define GLOBALS_BSP_DDRHSSPI
#include "abstract.h"
#include "mcu_settings.h"
#include "bsp_ddrhsspi.h"
#include "base_types.h"

/*****************************************************************************/
/* Global variable definitions (declared in header file with 'extern')       */
/*****************************************************************************/
/*****************************************************************************/
/* Local type definitions ('typedef')                                        */
/*****************************************************************************/
/*****************************************************************************/
/* Local function prototypes ('static')                                      */
/*****************************************************************************/
static int hsspi_CalibrationDlpDual(void);
static void hsspi_CheckQuadBitDual(void);
static int hsspi_CalibrationDlpSingle(void);//每隔一段时间调用一次
static void hsspi_CheckQuadBitSingle(void);
extern void bsp_HDOG_Feed(void);

/*****************************************************************************/
/* Local variable definitions ('static')                                     */
/*****************************************************************************/
#define HSSPI_START_ADDRESS   0x80000000

/*****************************************************************************/
/* Function implementation - global ('extern') and local ('static')          */
/*****************************************************************************/

static void InitGD25Q257D(void)
{    
    /******** Transfer in Direct Mode (Command:b7)********/
    DDRHSSPI0_DMBCC = 0x0002;        /*2.[bit15:0] Byte Count Control = 2*/
    DDRHSSPI0_TXFIFO0 = 0x000010b7;  /*  QUAD Flash. Write Enable (WREN 06h)*/
    DDRHSSPI0_TXFIFO0 = 0x00001000;  /*  Required command before Write VDLR (WVDLR 4Ah)*/
    DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
    while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
        ;
    }
    
    /******** Transfer in Direct Mode (Command:06)********/
    DDRHSSPI0_DMBCC = 0x0001;        /*2.[bit15:0] Byte Count Control = 2*/
    DDRHSSPI0_TXFIFO0 = 0x00001006;  /*  QUAD Flash. Write Enable (WREN 06h)*/
    DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
    while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
        ;
    }
    
    /******** Transfer in Direct Mode (Command:83)********/
    DDRHSSPI0_DMBCC = 0x0002;        /*2.[bit15:0] Byte Count Control = 4*/
    DDRHSSPI0_TXFIFO0 = 0x00001056;  /*  QUAD Flash. Write VDLR (WVDLR 83h)*/
    DDRHSSPI0_TXFIFO0 = 0x00001008;
    DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
    while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
        ;
    }
    
    /******** Transfer in Direct Mode (Command:06)********/
    DDRHSSPI0_DMBCC = 0x0001;        /*2.[bit15:0] Byte Count Control = 2*/
    DDRHSSPI0_TXFIFO0 = 0x00001006;  /*  QUAD Flash. Write Enable (WREN 06h)*/
    DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
    while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
        ;
    }
    
    /******** Transfer in Direct Mode (Command:4A)********/
    DDRHSSPI0_DMBCC = 0x0002;        /*2.[bit15:0] Byte Count Control = 4*/
    DDRHSSPI0_TXFIFO0 = 0x0000104A;  /*  QUAD Flash. Write VDLR (WVDLR 4Ah)*/
    DDRHSSPI0_TXFIFO0 = 0x00001034;
    DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
    while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
        ;
    }
}
/******************************************************************************
** \brief hsspi_SetSingleQuad
**
** \return Execution result
** \retval 0  :DLP Calibration Successful completion.
** \retval 1  :DLP Calibration failure. There is a line without Pass area.
**
*****************************************************************************/
int hsspi_SetSingleQuad(void)
{
    hsspi_CheckQuadBitSingle();  /*Check for QUAD bit in Configuration Register of QUAD Flash.*/
    /*If QUAD bit has been already set to 1, this function is unnecessary.*/
    
    InitGD25Q257D();
    /******** Direct Mode Configuration ********/
    DDRHSSPI0_PCC0 =  0x00010220;    /*1.[bit20:16]Slave Selection De-Assertion Timeout = 1: SDR = 4 x SCLK cycle, DDR = 3.5 x SCLK cycle(Minimum setting)*/
    /*  [bit12:9] Clock Division = 0: Divide by 2. SCLK:60MHz*/
    /*  [bit6:5]  Slave Select to Clock Delay = 1: 1.75 SCLK*/
    DDRHSSPI0_MCTRL = 0x00000000;    /*1.[bit1]    Command Sequencer Mode Enable = 0: Direct Mode is enabled. Command Sequencer Mode is disabled.*/
    DDRHSSPI0_DMTRP = 0x2A;          /*2.[bit5]    DDR Mode*/
    /*  [bit3:0]  Transfer Protocol: TX-Only in Quad Mode is configured.*/
    DDRHSSPI0_DMFIFOCFG = 0x001C080F;/*3.[bit20]   TX-FIFO Flush = 1: Writing "1" flushes the TX-FIFO and TX Shift Register.*/
    /*  [bit19]   RX-FIFO Flush = 1: Writing "1" flushes the RX-FIFO and RX Shift Register.*/
    /*  [bit18]   TXCTRL Bit to be Written to TX-FIFO*/
    /*  [bit17:16]FIFO Width = 0: TX-FIFO, RX-FIFO and Shift-Register are 8-bit wide.*/
    /*  [bit12:8] TX-FIFO Threshold Level = 8*/
    /*  [bit4:0]  RX-FIFO Threshold Level = 15*/
    DDRHSSPI0_TXE = 0x0;             /*  TX interrupts are not used.*/
    DDRHSSPI0_RXE = 0x0;             /*  RX interrupts are not used.*/
    DDRHSSPI0_TXC = 0x00000077;      /*  TX interrupt flags are cleared.*/
    DDRHSSPI0_RXC = 0x000000FB;      /*  RX interrupt flags are cleared.*/
    DDRHSSPI0_DMPSEL = 0x0;          /*  [bit1:0]  Peripheral Select = 0: oDDRHSSPIn_SSEL0 is asserted.*/
    DDRHSSPI0_MCTRL = 0x00000001;    /*5.[bit0]    Module Enable = 1: DDRHSSPI is enabled.*/
    DDRHSSPI0_DMCFG = 0x02;          /*Figure 4-10 Programmer's Flowchart: General Steps 3.*/
    /*  [bit1]   Slave Select De-Assertion Control = 1: Byte Counter Mode. DDRHSSPIn_DMBCC.BCC is used to decide when to de-assert the Slave Select.*/
    
    /******** Command Sequencer modeConfiguration ********/
    /* Set register RDCSDC according to S25FL256S manual "Figure 10.50 Continuous DDR Quad I/O Read Subsequent Access"*/
    DDRHSSPI0_RDCSDC0 = 0x0301;      /*  [bit15:8] RDCSDATA[7:0] Transmit address bits [31:24] of the Serial Flash Memory address*/
    DDRHSSPI0_RDCSDC1 = 0x0201;      /*  [bit15:8] RDCSDATA[7:0] Transmit address bits [23:16] of the Serial Flash Memory address*/
    DDRHSSPI0_RDCSDC2 = 0x0101;      /*  [bit15:8] RDCSDATA[7:0] Transmit address bits [15:8] of the Serial Flash Memory address*/
    DDRHSSPI0_RDCSDC3 = 0x0001;      /*  [bit15:8] RDCSDATA[7:0] Transmit address bits [7:0] of the Serial Flash Memory address*/
    DDRHSSPI0_RDCSDC4 = 0xa500;      /*  [bit15:8] RDCSDATA[7:0] If DEC bit is "0", the data byte in RDCSDATA[7:0] is transmitted as Mode*/
    DDRHSSPI0_RDCSDC5 = 0x3401;      /*  [bit15:8] RDCSDATA[7:0] RDCSDATA[2:0] = 0b100: Dummy cycle(s) on the SDATA output lines for RDCSDATA [7:3] number of SCLK cycles.*/
    DDRHSSPI0_RDCSDC6 = 0x0701;      /*  [bit15:8] RDCSDATA[7:0] End of list*/
    
    /******** Transfer in Direct Mode (Command:06)********/
    //DDRHSSPI0_DMBCC = 0x0001;        /*2.[bit15:0] Byte Count Control = 1*/
    //DDRHSSPI0_TXFIFO0 = 0x00001006;  /*  QUAD Flash. Write Enable (WREN 06h)   Required command before Write VDLR (WVDLR 4Ah)*/
    //DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
    //while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
    //    ;
    //}
    //
    ///******** Transfer in Direct Mode (Command:4A)********/
    //DDRHSSPI0_DMBCC = 0x0002;        /*2.[bit15:0] Byte Count Control = 2*/
    //DDRHSSPI0_TXFIFO0 = 0x0000104A;  /*  QUAD Flash. Write VDLR (WVDLR 4Ah)*/
    //DDRHSSPI0_TXFIFO0 = 0x00001034;  /*Non-Volatile Data Learning Register (NVDLR) DLP setting*/
    //DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
    //while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
    //    ;
    //}
    
    /******** Transfer in Direct Mode (Command:EE)********/
    DDRHSSPI0_DMBCC = 0x000c;        /*2.[bit15:0] Byte Count Control = 12*/
    DDRHSSPI0_TXFIFO0 = 0x000010EE;  /*  QUAD Flash. DDR Quad I/O Read (EEh)*/
    DDRHSSPI0_TXFIFO0 = 0x00001600;  /*32 Bit Address*/
    DDRHSSPI0_TXFIFO0 = 0x00001600;
    DDRHSSPI0_TXFIFO0 = 0x00001600;
    DDRHSSPI0_TXFIFO0 = 0x00001600;  /*Mode*/
    DDRHSSPI0_TXFIFO0 = 0x000016a5;  /*6 cycle Dummy*/
    DDRHSSPI0_TXFIFO0 = 0x00000000;  /*  QUAD Flash. Configuration Register (CR1) LC[7:6]=0*/
    DDRHSSPI0_TXFIFO0 = 0x00000000;
    DDRHSSPI0_TXFIFO0 = 0x00000000;
    DDRHSSPI0_TXFIFO0 = 0x00000000;
    DDRHSSPI0_TXFIFO0 = 0x00000000;
    DDRHSSPI0_TXFIFO0 = 0x00000000;
    DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
    while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
        bsp_HDOG_Feed();
    }
    
    /******** DLP Calibration ********/
    DDRHSSPI0_CSCFG = 0x008F010C;    /*3.[bit23]    ITIMER is enabled. SSEL is de-asserted after the time expiration, that has been programmed in DDRHSSPIn_CSITIME Register.*/
    /*  [bit19:16] Slave Select MSEL0~3*/
    /*  [bit8]     Slave Select 0 Enable*/
    /*  [bit3]     DDR Mode in Command Sequencer Mode.*/
    /*  [bit2:1]   Serial transfer works at Quad Protocol. Read data is sampled on SDATA[3:0].*/
    DDRHSSPI0_DLP = 0x34;            /*It must be set the same as QUAD Flash.*/
    /*  [bit7:0]   Data Learning Pattern*/
    return hsspi_CalibrationDlpSingle();
    
}

/******************************************************************************
** \brief hsspi_CheckQuadBitSingle
**
** \note
**
** \post
**
*****************************************************************************/
void hsspi_CheckQuadBitSingle(void)
{
    unsigned int RXFIFO[4];
    
    /*DDRHSSPI    Cypress S25FL256S*/
    /******** Direct Mode Configuration ********   Figure 4-11 Programmer's Flowchart: DDRHSSPI in Direct Mode of Operation*/
    DDRHSSPI0_PCC0 =  0x00010220;    /*1.[bit20:16]Slave Selection De-Assertion Timeout = 1: SDR = 4 x SCLK cycle, DDR = 3.5 x SCLK cycle(Minimum setting)*/
    /*  [bit12:9] Clock Division = 1: Divide by 4. SCLK:60MHz*/
    /*  [bit6:5]  Slave Select to Clock Delay = 1: 1.75 SCLK*/
    DDRHSSPI0_MCTRL = 0x00000000;    /*1.[bit1]    Command Sequencer Mode Enable = 0: Direct Mode is enabled. Command Sequencer Mode is disabled.*/
    DDRHSSPI0_DMTRP = 0x00;          /*2.[bit5]    SDR Mode*/
    /*  [bit3:0]  Transfer Protocol: TX-and-RX in Legacy Mode is configured.*/
    DDRHSSPI0_DMFIFOCFG = 0x001C080F;/*3.[bit20]   TX-FIFO Flush = 1: Writing "1" flushes the TX-FIFO and TX Shift Register.*/
    /*  [bit19]   RX-FIFO Flush = 1: Writing "1" flushes the RX-FIFO and RX Shift Register.*/
    /*  [bit18]   TXCTRL Bit to be Written to TX-FIFO*/
    /*  [bit17:16]FIFO Width = 0: TX-FIFO, RX-FIFO and Shift-Register are 8-bit wide.*/
    /*  [bit12:8] TX-FIFO Threshold Level = 8*/
    /*  [bit4:0]  RX-FIFO Threshold Level = 15*/
    DDRHSSPI0_TXE = 0x0;             /*  TX interrupts are not used.*/
    DDRHSSPI0_RXE = 0x0;             /*  RX interrupts are not used.*/
    DDRHSSPI0_TXC = 0x00000077;      /*  TX interrupt flags are cleared.*/
    DDRHSSPI0_RXC = 0x000000FB;      /*  RX interrupt flags are cleared.*/
    DDRHSSPI0_DMPSEL = 0x0;          /*  [bit1:0]  Peripheral Select = 0: oDDRHSSPIn_SSEL0 is asserted.*/
    DDRHSSPI0_MCTRL = 0x00000001;    /*5.[bit0]    Module Enable = 1: DDRHSSPI is enabled.*/
    DDRHSSPI0_DMCFG = 0x02;          /*Figure 4-10 Programmer's Flowchart: General Steps 3.*/
    /*  [bit1]   Slave Select De-Assertion Control = 1: Byte Counter Mode. DDRHSSPIn_DMBCC.BCC is used to decide when to de-assert the Slave Select.*/
    
    bsp_HDOG_Feed();
    /******** Transfer in Direct Mode (Command:F0)********/
    DDRHSSPI0_DMBCC = 0x0002;        /*2.[bit15:0] Byte Count Control = 2*/
    DDRHSSPI0_TXFIFO0 = 0x00001066;  /*  QUAD Flash. Software Reset Command (RESET F0h)*/
    DDRHSSPI0_TXFIFO0 = 0x00001000;
    DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
    while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
        ;
    }
    DDRHSSPI0_DMBCC = 0x0002;        /*2.[bit15:0] Byte Count Control = 2*/
    DDRHSSPI0_TXFIFO0 = 0x00001099;  /*  QUAD Flash. Software Reset Command (RESET F0h)*/
    DDRHSSPI0_TXFIFO0 = 0x00001000;
    DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
    while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
        ;
    }
    
    DDRHSSPI0_DMBCC = 0x0001;        /*2.[bit15:0] Byte Count Control = 2*/
    DDRHSSPI0_TXFIFO0 = 0x00001006;  /*  QUAD Flash. Software Reset Command (RESET F0h)*/
    DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
    while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
        ;
    }
    
    DDRHSSPI0_DMBCC = 0x0002;        /*2.[bit15:0] Byte Count Control = 2*/
    DDRHSSPI0_TXFIFO0 = 0x00001031;  /*  QUAD Flash. Software Reset Command (RESET F0h)*/
    DDRHSSPI0_TXFIFO0 = 0x00001002;
    DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
    while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
        ;
    }
  
    while(1)                                   /*Check completion of Software Reset of QUAD Flash*/
    {
        DDRHSSPI0_DMFIFOCFG_TXFLSH = 1;  /*  TX-FIFO Flush = 1: Writing "1" flushes the TX-FIFO and TX Shift Register.*/
        DDRHSSPI0_DMFIFOCFG_RXFLSH = 1;  /*  RX-FIFO Flush = 1: Writing "1" flushes the RX-FIFO and RX Shift Register.*/
        
        /******** Transfer in Direct Mode (Command:05)********/
        DDRHSSPI0_DMBCC = 0x0002;        /*2.[bit15:0] Byte Count Control = 2*/
        DDRHSSPI0_TXFIFO0 = 0x00001005;  /*  QUAD Flash. Read Status Register-1 (RDSR1 05h)   WIP(Write in Progress) bit is checked.*/
        DDRHSSPI0_TXFIFO0 = 0x00001000;  /*  Get 1 byte of register data.*/
        DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
        while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
            bsp_HDOG_Feed();
        }
        
        RXFIFO[0] = DDRHSSPI0_RXFIFO0;  /*Read Instruction part*/
        RXFIFO[1] = DDRHSSPI0_RXFIFO1;  /*Read Configuration Register part*/
               
        if((RXFIFO[1] & 0x01) == 0x0){
                break;
        }       
        bsp_HDOG_Feed();
    }
    
    /******** Transfer in Direct Mode (Command:35)********/
    DDRHSSPI0_DMBCC = 0x0002;        /*2.[bit15:0] Byte Count Control = 2*/
    DDRHSSPI0_TXFIFO0 = 0x00001035;  /*  QUAD Flash. Read Configuration Register-1 (RDCR 35h)   Latency Code and QUAD bit are checked.*/
    DDRHSSPI0_TXFIFO0 = 0x00001000;  /*  Get 1 byte of register data.*/
    DDRHSSPI0_DMSTART_START = 0x01;  /*7.[bit0]    Start Transfer = 1*/
    while(DDRHSSPI0_DMSTART_START){  /* In case of user program, countermeasure of infinite loop is recommended. */
        ;
    }
    
    RXFIFO[0] = DDRHSSPI0_RXFIFO0;   /*Read Instruction part*/
    RXFIFO[1] = DDRHSSPI0_RXFIFO1;   /*Read Status Register part*/
}

/******************************************************************************
** \brief hsspi_CalibrationDlpSingle
**
** \return Execution result
** \retval 0  :DLP Calibration Successful completion.
** \retval 1  :DLP Calibration failure. There is a line without Pass area.
**
*****************************************************************************/
static int hsspi_CalibrationDlpSingle(void)
{
    
    /* NOTE: Please execute "GRPSUB_BUSM_MonitorInterruptEnable = 0x0;" at main() only once */
    
    unsigned char i_SamplingPoints,i_BitLanes;
    unsigned int passWindowSize=0;
    volatile unsigned int test=0;
    volatile unsigned int dummyRead=0;
    unsigned int dlpStatus[64];
    unsigned int passWindowTotal[4];
    volatile unsigned int *data;
    volatile unsigned int *dlpCheckAddress;
    
    /*init*/
    DDRHSSPI0_SDATASAMPLEPTCNT0 = 0x00;
    DDRHSSPI0_SDATASAMPLEPTCNT1 = 0x00;
    DDRHSSPI0_SDATASAMPLEPTCNT2 = 0x00;
    DDRHSSPI0_SDATASAMPLEPTCNT3 = 0x00;
    
    for(i_SamplingPoints=0;i_SamplingPoints<64;i_SamplingPoints++)
    {
        dlpStatus[i_SamplingPoints]=0;
    }
    for(i_BitLanes=0;i_BitLanes<4;i_BitLanes++)
    {
        passWindowTotal[i_BitLanes]=0;
    }
    
    data = (unsigned int *)HSSPI_START_ADDRESS;
    
    /*Command Sequencer mode*/
    DDRHSSPI0_MCTRL = 0x00000023;    /*  [bit5]    Data Learning Pattern Enable = 1: DLP is enabled.*/
    /*  [bit1]    Command Sequencer Mode Enable = 1: Command Sequencer Mode is enabled. Direct Mode is disabled.*/
    /*  [bit0]    Module Enable = 1: DDRHSSPI is enabled.*/
    //add by zhangxuesong 2018_03_13_17_32
#if 1
    for(i_SamplingPoints=0;i_SamplingPoints<64;i_SamplingPoints++)
    {
        test=*data;
        dlpStatus[i_SamplingPoints] = DDRHSSPI0_DLPSAMPLESTATUS;  /*Status of DLP patterns recorded on each SDATA[7:0] input ports.*/
        
        DDRHSSPI0_SDATASAMPLEPTCNT0 = DDRHSSPI0_SDATASAMPLEPTCNT0 + 0x1;
        DDRHSSPI0_SDATASAMPLEPTCNT1 = DDRHSSPI0_SDATASAMPLEPTCNT1 + 0x1;
        DDRHSSPI0_SDATASAMPLEPTCNT2 = DDRHSSPI0_SDATASAMPLEPTCNT2 + 0x1;
        DDRHSSPI0_SDATASAMPLEPTCNT3 = DDRHSSPI0_SDATASAMPLEPTCNT3 + 0x1;
        
        DDRHSSPI0_SDATASAMPLEPTLFT0 = DDRHSSPI0_SDATASAMPLEPTCNT0;
        DDRHSSPI0_SDATASAMPLEPTLFT1 = DDRHSSPI0_SDATASAMPLEPTCNT1;
        DDRHSSPI0_SDATASAMPLEPTLFT2 = DDRHSSPI0_SDATASAMPLEPTCNT2;
        DDRHSSPI0_SDATASAMPLEPTLFT3 = DDRHSSPI0_SDATASAMPLEPTCNT3;
        
        DDRHSSPI0_SDATASAMPLEPTRGH0 = DDRHSSPI0_SDATASAMPLEPTCNT0;
        DDRHSSPI0_SDATASAMPLEPTRGH1 = DDRHSSPI0_SDATASAMPLEPTCNT1;
        DDRHSSPI0_SDATASAMPLEPTRGH2 = DDRHSSPI0_SDATASAMPLEPTCNT2;
        DDRHSSPI0_SDATASAMPLEPTRGH3 = DDRHSSPI0_SDATASAMPLEPTCNT3;
        
        /* 8byte increment*/
        data += 2;
        
    }
#endif
    //end by zhangxuesong 
    /*Command Sequencer mode*/
    DDRHSSPI0_MCTRL = 0x00000003;    /*  [bit5]    Data Learning Pattern Enable = 0: DLP is disabled.*/
    /*  [bit1]    Command Sequencer Mode Enable = 1: Command Sequencer Mode is enabled. Direct Mode is disabled.*/
    /*  [bit0]    Module Enable = 1: DDRHSSPI is enabled.*/
    for(i_BitLanes=0;i_BitLanes<4;i_BitLanes++)
    {
        for(i_SamplingPoints=0;i_SamplingPoints<64;i_SamplingPoints++)
        {
            if(((dlpStatus[i_SamplingPoints] >> i_BitLanes*4) & 0x0000000F) == 0x0)
            {
                passWindowTotal[i_BitLanes] = passWindowTotal[i_BitLanes] + i_SamplingPoints;
                passWindowSize++;
            }
            if(((dlpStatus[i_SamplingPoints] >> i_BitLanes*4) & 0x0000000F) != 0x0  && passWindowSize !=0)
            {
                i_SamplingPoints=64;/*finish*/
            }
        }
        if( passWindowSize ==0 )
        {
            return HSSPI_ERROR;
        }
        
        passWindowTotal[i_BitLanes] = passWindowTotal[i_BitLanes]/passWindowSize;
        passWindowSize = 0;
        bsp_HDOG_Feed();
    }
    
    DDRHSSPI0_SDATASAMPLEPTCNT0 = passWindowTotal[0];  /*  [bit6:0]  This field defines, for an incoming SDATA0 port, sample clock delay.*/
    DDRHSSPI0_SDATASAMPLEPTCNT1 = passWindowTotal[1];  /*  [bit6:0]  This field defines, for an incoming SDATA1 port, sample clock delay.*/
    DDRHSSPI0_SDATASAMPLEPTCNT2 = passWindowTotal[2];  /*  [bit6:0]  This field defines, for an incoming SDATA2 port, sample clock delay.*/
    DDRHSSPI0_SDATASAMPLEPTCNT3 = passWindowTotal[3];
                                  
    DDRHSSPI0_SDATASAMPLEPTLFT0 = DDRHSSPI0_SDATASAMPLEPTCNT0;  /*  [bit6:0]  SDATA0 Left Clock Sample Point Control*/
    DDRHSSPI0_SDATASAMPLEPTLFT1 = DDRHSSPI0_SDATASAMPLEPTCNT1;  /*  [bit6:0]  SDATA1 Left Clock Sample Point Control*/
    DDRHSSPI0_SDATASAMPLEPTLFT2 = DDRHSSPI0_SDATASAMPLEPTCNT2;  /*  [bit6:0]  SDATA2 Left Clock Sample Point Control*/
    DDRHSSPI0_SDATASAMPLEPTLFT3 = DDRHSSPI0_SDATASAMPLEPTCNT3;
                                  
    DDRHSSPI0_SDATASAMPLEPTRGH0 = DDRHSSPI0_SDATASAMPLEPTCNT0;  /*  [bit6:0]  SDATA0 Right Clock Sample Point Control*/
    DDRHSSPI0_SDATASAMPLEPTRGH1 = DDRHSSPI0_SDATASAMPLEPTCNT1;  /*  [bit6:0]  SDATA1 Right Clock Sample Point Control*/
    DDRHSSPI0_SDATASAMPLEPTRGH2 = DDRHSSPI0_SDATASAMPLEPTCNT2;  /*  [bit6:0]  SDATA2 Right Clock Sample Point Control*/
    DDRHSSPI0_SDATASAMPLEPTRGH3 = DDRHSSPI0_SDATASAMPLEPTCNT3;
    
    /*When the software runs a Calibration sequence to adjust the SDATA Sampling Points, it is important to see*/
    /*if the following two addresses are different at least by 8 bytes (assuming 32-bits access).*/
        /*  - The last address of Calibration sequence*/
    /*  (The last Memory Read access in the Calibration is expected to be an error.)*/
    /*  - The start address of Memory Read access in the normal process*/
    dlpCheckAddress = (unsigned int *)HSSPI_START_ADDRESS;
    dummyRead = *dlpCheckAddress;
    return HSSPI_PASS;
}

/******************************************************************************
** \brief START checking
**
** \note
**
** \post
**
*****************************************************************************/

#define PPC_SET         0x00010020      //bit20:16  SSELDEASRT[4:0]=1   De-assertion time = 3.5 x SCLKcycle
//bit6:5    SS2CD[1:0]=1        Slave Select to Clock Delay= 1.5 x SCLKcycle
#define SSELx_SET       0x00
#define DMFIFOCFG_SET   0x0005080F      //"DMFIFOCFG=0x0004_080F (TXCTRL=1, [bit17:16]FWIDTH=01)"
#define DMTRP_SET       0x0B


static void START(void)
{
    unsigned char temp = 0x01;
    
    while(1)                              //check START "1" =>"0"
    {
        if (temp == 0x0)
        {
            break;
        }
        temp = DDRHSSPI0_DMSTART_START;
        bsp_HDOG_Feed();
    }
    temp = 0x01;
}


/******************************************************************************
** \brief START checking
**
** \note
**
** \post
**
*****************************************************************************/
void Dual_Sctr_Ers(unsigned long topAddress)
{
    unsigned int wait;
    unsigned int RXFIFO0;
    unsigned int RXFIFO1;
    unsigned int RXFIFO2;
    unsigned int RXFIFO3;
    unsigned int RXFIFO4;
    
    union
    {
        struct
        {
            uint32_t u4_0:4;
            uint32_t u4_1:4;
            uint32_t u4_2:4;
            uint32_t u4_3:4;
            uint32_t u4_4:4;
            uint32_t u4_5:4;
            uint32_t u4_6:4;
            uint32_t u4_7:4;
        } bit4;
        uint32_t u32;
    } addrUtil;
    
    addrUtil.u32 = topAddress;
    
    //DDRHSSPI
    //Direct Mode
    DDRHSSPI0_MCTRL = 0x00000000;
    DDRHSSPI0_DMTRP = 0x03;
    DDRHSSPI0_PCC0 = PPC_SET;
    DDRHSSPI0_MCTRL = 0x00000001;
    DDRHSSPI0_DMCFG = 0x02;
    DDRHSSPI0_DMPSEL = SSELx_SET;                // [bit1:0] PSEL[1:0] not select sametime!
    DDRHSSPI0_DMFIFOCFG = DMFIFOCFG_SET;
    
    DDRHSSPI0_DMBCC = 0x0004;
    DDRHSSPI0_TXFIFO0 = 0x00001033;
    DDRHSSPI0_TXFIFO0 = 0x00001055;
    DDRHSSPI0_TXFIFO0 = 0x00001000;
    DDRHSSPI0_TXFIFO0 = 0x00001000;//CR1 Read
    DDRHSSPI0_DMSTART_START = 0x01;
    
    START();
    
    // HSSPI0_DMSTATUS_TXACTIVE
    while(DDRHSSPI0_DMFIFOSTATUS_SSACTIVE != 0)
    {
        // H/W WDT Clear
        HWDG_TRG0 = 0;
        HWDG_TRG1 = 0;
    }
    
    // HS-SPI Tx-FIFO設定レジスタ
    DDRHSSPI0_DMFIFOCFG_TXFLSH = 1;     //1: Flushes the TX-FIFO
    DDRHSSPI0_DMFIFOCFG_RXFLSH = 1;     //1: Flushes the RX-FIFO
    
    //BYTE ACCESS
    
    
    DDRHSSPI0_DMBCC = 0x0002;
    DDRHSSPI0_TXFIFO0 = 0x00001000;
    DDRHSSPI0_TXFIFO0 = 0x00001066;
    DDRHSSPI0_DMSTART_START = 0x01;
    
    START();
    
    for (wait = 0; wait < 100; wait++);
    
    //BYTE ACCESS
    
    
    DDRHSSPI0_DMBCC = 0x000A;
    DDRHSSPI0_TXFIFO0 = 0x000010DD; // 0xDC is a command for sector erase,
    DDRHSSPI0_TXFIFO0 = 0x000010CC; // This command is followed by a 4-byte address
    DDRHSSPI0_TXFIFO0 = (0x00001000 + addrUtil.bit4.u4_7 * 0x11);
    DDRHSSPI0_TXFIFO0 = (0x00001000 + addrUtil.bit4.u4_6 * 0x11);
    DDRHSSPI0_TXFIFO0 = (0x00001000 + addrUtil.bit4.u4_5 * 0x11);
    DDRHSSPI0_TXFIFO0 = (0x00001000 + addrUtil.bit4.u4_4 * 0x11);;
    DDRHSSPI0_TXFIFO0 = (0x00001000 + addrUtil.bit4.u4_3 * 0x11);;
    DDRHSSPI0_TXFIFO0 = (0x00001000 + addrUtil.bit4.u4_2 * 0x11);;
    DDRHSSPI0_TXFIFO0 = (0x00001000 + addrUtil.bit4.u4_1 * 0x11);;
    DDRHSSPI0_TXFIFO0 = (0x00001000 + addrUtil.bit4.u4_0 * 0x11);;
    DDRHSSPI0_DMSTART_START = 0x01;
    
    START();
    
    // HSSPI0_DMSTATUS_TXACTIVE
    while(DDRHSSPI0_DMFIFOSTATUS_SSACTIVE != 0)
    {
        // H/W WDT Clear
        bsp_HDOG_Feed();
    }
    
    // HS-SPI Tx-FIFO設定レジスタ
    DDRHSSPI0_DMFIFOCFG_TXFLSH = 1;     //1: Flushes the TX-FIFO
    DDRHSSPI0_DMFIFOCFG_RXFLSH = 1;     //1: Flushes the RX-FIFO
    
    RXFIFO0 = 0x66;
    RXFIFO1 = 0x66;
    
    while(1)
    {
        
        //BYTE ACCESS
        
        
        bsp_HDOG_Feed();
        
        DDRHSSPI0_DMBCC = 0x0004;
        DDRHSSPI0_TXFIFO0 = 0x00001000;
        DDRHSSPI0_TXFIFO0 = 0x00001055;
        DDRHSSPI0_TXFIFO0 = 0x00001000;
        DDRHSSPI0_TXFIFO0 = 0x00001000;//SR1 Read
        DDRHSSPI0_DMSTART_START = 0x01;
        
        START();
        
        RXFIFO0 = DDRHSSPI0_RXFIFO0;
        RXFIFO1 = DDRHSSPI0_RXFIFO1;
        RXFIFO2 = DDRHSSPI0_RXFIFO2;
        RXFIFO3 = DDRHSSPI0_RXFIFO3;
        RXFIFO4 = DDRHSSPI0_RXFIFO4;
        
        if((RXFIFO3 & 0x03) == 0x0){
                break;
        }
        
    }
    
    
    for (wait = 0; wait < 100000; wait++);
    
}

void Flsh_Rst(void)
{
    //DDRHSSPI
    //Direct Mode
    DDRHSSPI0_MCTRL = 0x00000000;
    DDRHSSPI0_DMTRP = DMTRP_SET;
    DDRHSSPI0_PCC0 = PPC_SET;
    DDRHSSPI0_MCTRL = 0x00000001;
    DDRHSSPI0_DMCFG = 0x02;
    DDRHSSPI0_DMPSEL = SSELx_SET;
    DDRHSSPI0_DMFIFOCFG = DMFIFOCFG_SET;
    
    DDRHSSPI0_DMBCC = 0x0002;
    DDRHSSPI0_TXFIFO0 = 0x000010FF; // MBR
    DDRHSSPI0_TXFIFO0 = 0x000010FF; // MBR
    DDRHSSPI0_DMSTART_START = 0x01;
    
    START();
}
/******************************************************************************
** \brief START checking
**
** \note
**
** \post
**
*****************************************************************************/


void DualQuad_MCU_SDR_Write(uint32_t *startAddr, uint32_t size, uint32_t destinationOffsetAddr)
{
    unsigned int i, RXFIFO0, RXFIFO1, RXFIFO2, RXFIFO3, RXFIFO4;
    unsigned int FL256S_AD15_8bit;
    unsigned int add, bit;
    uint32_t WriteTxfifo;
    
    size /= 2;
    destinationOffsetAddr /= 2;
    
    //DDRHSSPI
    //Direct Mode
    DDRHSSPI0_MCTRL = 0x00000000;
    DDRHSSPI0_DMTRP = DMTRP_SET;
    DDRHSSPI0_PCC0 = PPC_SET;
    DDRHSSPI0_DMCFG = 0x02;
    DDRHSSPI0_DMPSEL = SSELx_SET;
    DDRHSSPI0_DMFIFOCFG = DMFIFOCFG_SET;
    DDRHSSPI0_CSCFG = 0x000F0104;  //"CSCFG=0x000F_0104 (NOCTAL=0, MSEL=4'b1111, SSEL(3:0)=4'b0001, DDRM=0, MBM=2'b10)"
    
    DDRHSSPI0_MCTRL = 0x00000001;
    
    bsp_HDOG_Feed();
    
    i = 0;
    for(add=destinationOffsetAddr; add < size+destinationOffsetAddr ; add=add+0x100)
    {
        DDRHSSPI0_MCTRL = 0x00000000;
        DDRHSSPI0_DMTRP = DMTRP_SET;
        DDRHSSPI0_MCTRL = 0x00000001;
        
        DDRHSSPI0_DMBCC = 0x0002;
        DDRHSSPI0_TXFIFO0 = 0x00001000;//write enable command(06h)
        DDRHSSPI0_TXFIFO0 = 0x00001066;
        DDRHSSPI0_DMSTART_START = 0x01;
        
        START();
        
        DDRHSSPI0_DMBCC = 0x0228;   // data[256Byte] x 2 + コマンド他[40byte]
        
        DDRHSSPI0_TXFIFO0 = 0x00001300; //Command 3
        DDRHSSPI0_TXFIFO0 = 0x00001300; //Command 3
        DDRHSSPI0_TXFIFO0 = 0x00001311; //Command 3
        DDRHSSPI0_TXFIFO0 = 0x00001311; //Command 3
        DDRHSSPI0_TXFIFO0 = 0x00001300; //Command 4
        DDRHSSPI0_TXFIFO0 = 0x00001311; //Command 4
        DDRHSSPI0_TXFIFO0 = 0x00001300; //Command 4
        DDRHSSPI0_TXFIFO0 = 0x00001300; //Command 4
        
        // HS-SPI送信割り込みクリアレジスタ
        DDRHSSPI0_TXC = 0x00000077;
        DDRHSSPI0_DMSTART_START = 1;        //SPI_CS high-to-Low
        
        FL256S_AD15_8bit = 0x00001300;
        
        for(bit = 0;bit < 32 ; bit++){
            DDRHSSPI0_TXFIFO0 = FL256S_AD15_8bit + (unsigned char)(((add >> 31 - bit) & 0x1) * 0x11);
        }
        
        WriteTxfifo = *(startAddr + i);
            
        while(DDRHSSPI0_DMBCS != 0) //(0x0228 - 送信完了したByte値)がDDRHSSPI0_DMBCS
        {
            while(DDRHSSPI0_TXF_TFLETS != 1);
            
            DDRHSSPI0_TXFIFO18 = 0x00001300 + (unsigned char)WriteTxfifo;
            DDRHSSPI0_TXFIFO19 = 0x00001300 + (unsigned char)(WriteTxfifo >> 8);
            DDRHSSPI0_TXFIFO20 = 0x00001300 + (unsigned char)(WriteTxfifo >> 16);
            DDRHSSPI0_TXFIFO21 = 0x00001300 + (unsigned char)(WriteTxfifo >> 24);
                i++;
            
            WriteTxfifo = *(startAddr + i);
                // HS-SPI送信割り込みクリアレジスタ
            DDRHSSPI0_TXC = 0x00000077;
            bsp_HDOG_Feed();
        }
        
        START();
        
        RXFIFO3 = 0x66;
        DDRHSSPI0_DMAEN_TXDMAEN = 0;
        
        DDRHSSPI0_MCTRL = 0x00000000;
        DDRHSSPI0_DMTRP = 0x03;
        DDRHSSPI0_MCTRL = 0x00000001;
        
        while(1)
        {
            //BYTE ACCESS
            
            bsp_HDOG_Feed();
            DDRHSSPI0_DMBCC = 0x0004;
            DDRHSSPI0_TXFIFO0 = 0x00001000;
            DDRHSSPI0_TXFIFO0 = 0x00001055;
            DDRHSSPI0_TXFIFO0 = 0x00001000;
            DDRHSSPI0_TXFIFO0 = 0x00001000;//SR1 Read
            DDRHSSPI0_DMSTART_START = 0x01;
            
            START();
            
            RXFIFO0 = DDRHSSPI0_RXFIFO0;
            RXFIFO1 = DDRHSSPI0_RXFIFO1;
            RXFIFO2 = DDRHSSPI0_RXFIFO2;
            RXFIFO3 = DDRHSSPI0_RXFIFO3;
            
            if((RXFIFO3 & 0x03) == 0x0){
                    break;
            }
            
        }
        DDRHSSPI0_MCTRL = 0x00000000;       // HSSPI0_MCTRL_MEN = 0: Module is disabled
    }
    
}




/******************************************************************************
** \brief HSSPI_port_GFX
**
** \note
**  Port Configuration
** \post
**
*****************************************************************************/
void HSSPI_port_GFX(void)
{
    SYSC0_PROTKEYR = 0x5CACCE55;
    SYSC0_SPECFGR_IO35RSTC = 0;     // 3V/5VIO reset release
    
    SYSC0_PROTKEYR = 0x5CACCE55;
    SYSC0_SPECFGR_IO3RSTC  = 0;     // 3VIO reset release
    
    
    WPREG_PPC(PPC_PCFGR019, 0x10C2);  // SDATA0_0  PPC_PCFGR:ODR[1:0] = 11 (10mA)
    WPREG_PPC(PPC_PCFGR021, 0x10C2);  // SDATA0_1
    WPREG_PPC(PPC_PCFGR020, 0x10C2);  // SDATA0_2
    WPREG_PPC(PPC_PCFGR023, 0x10C2);  // SDATA0_3
    
    //WPREG_PPC(PPC_PCFGR013, 0x10C2);  // SDATA1_0
    //WPREG_PPC(PPC_PCFGR015, 0x10C2);  // SDATA1_1
    //WPREG_PPC(PPC_PCFGR014, 0x10C2);  // SDATA1_2
    //WPREG_PPC(PPC_PCFGR017, 0x10C2);  // SDATA1_3
    
    WPREG_PPC(PPC_PCFGR022, 0x10C2);  // SSEL0
    //WPREG_PPC(PPC_PCFGR016, 0x10C2);  // SSEL1
    
    WPREG_PPC(PPC_PCFGR018, 0x10C2);  // SCLK0  Q26
    //Enable I/O Ports
    Port_EnableInput();
}
void BSP_QSPI_Init(void)
{
    HSSPI_port_GFX();
    while(hsspi_SetSingleQuad() == HSSPI_ERROR)
    {
        hsspi_SetSingleQuad();
    }
}
//@}
//#endif //(PDL_PERIPHERAL_HSSPI_ACTIVE)
/*****************************************************************************/
/* EOF (not truncated)                                                       */
/*****************************************************************************/

