/********************************************************************************/
/*  CONFIDENTIAL                                                                */
/*  Copyright(c) 2011-2012 Yamaha Corporation. All rights reserved.             */
/*  Module          : $Workfile: YGV642.c $                                     */
/*  Description     : YGV642 Driver Function                                    */
/*  Version         : $Rev: 162 $                                               */
/*  Last UpDate Time: $Date:: 2012-08-28 18:04:15#$                             */
/*  FOOT NOTE       : adjust 2tab                                               */
/*  AUTHOR          : H.Katayama                                                */
/********************************************************************************/

/*------------------------------------------------------------------------------*/
/*                      I N C L U D E                                           */
/*------------------------------------------------------------------------------*/
#include "YGV642.h"

#if   defined USE_LCD_HSD043I9W1
  #include  "LCD_HSD043I9W1.h"
#elif defined USE_LCD_AUOC035QAN01
  #include  "LCD_AUOC035QAN01.h"
#elif defined USE_LCD_CPTCLAP070LM01XN
  #include  "LCD_CPTCLAP070LM01XN.h"
#else
  #error    Select LCD panel in YvcConfig.h
#endif


extern void YGV642_Pattern_Memory_Init(void);

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Init                                               */
/* Contents         : Device initialization                                     */
/* Argument         : void                                                      */
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
void YGV642_Init(void)
{
  uint8_t     PLLReg[2];
  uint16_t    LyrEndAddr;
  
  T_Y642_R30H tY642R30H;
  T_Y642_R3EH tY642R3EH;
  T_Y642_R3FH tY642R3FH;
	T_Y642_R40H tY642R40H;
	T_Y642_R41H tY642R41H;
  
  wdt_reset();
  
  /*--- In the case of PLL setting judgment PLLR and PLLF=0,  */
  /*                    it is judged as a terminal setup.  ---*/
  if ( (tYvc1Data.Clk[0] == 0x00) && (tYvc1Data.Clk[1] == 0x00) )
  {
    /*------------------------------------------------------------------*/
    /* Pin Controlled PLL Configuration                                 */
    /*------------------------------------------------------------------*/
    /* 1.Hardware Reset                                                 */
    /*   It needs to be carried out before this function.               */
    /*                                                                  */
    /* 2.PLL Lock-up Phase                                              */
    /*   P#2: INIEND becomes 1 when PLL achieves lock.                  */
    /*   *PLL Lock-up Phase (XIN clock cycle x 20000)                   */
    /*    takes 1 ms (at 20 MHz) to 3.4 ms (at 6 MHz).                  */

    YGV642_Wait_ms(YVC1_PLL_LOCKUP_WAIT);
    YGV642_INIEND_Wait_Polling();    

    /* 3.Reconfiguration Registers                                      */
    /*   (1) Set Clock Control register (R#03h).                        */
    /*   (2) Set Display Scan Control register (R#06h-#1Ch).            */
    /*       (*To use the timing controller function,set Timing         */
    /*         Controller register (R#67h-#7Dh).                        */
    
    YGV642_Write_Reg(REG_R03H, tYvc1Data.Clk[2]);               /* (1)	*/
    
    YGV642_Write_Regs(REG_R06H, tYvc1Data.Disp, 23);            /* (2)	*/
	  YGV642_Write_Reg(REG_R31H, tYvc1Data.VideoOut);
    YGV642_Write_Regs(REG_R67H, tYvc1Data.TCON, 23);
  }
  else
  {
    /*------------------------------------------------------------------*/
    /* Register Controlled PLL Configuration                            */
    /*------------------------------------------------------------------*/
    /* 1.Hardware Reset                                                 */
    /*   It needs to be carried out before this function.               */
    /* 2.PLL Lock-up Phase                                              */
    /*   P#2: INIEND becomes 1 when PLL achieves lock.                  */
    /*   *PLL Lock-up Phase (XIN clock cycle x 20000) takes             */
    /*    1ms (at 20MHz) to 3.4ms (at 6 MHz).                           */

    YGV642_Wait_ms(YVC1_PLL_LOCKUP_WAIT);
    YGV642_INIEND_Wait_Polling(); 

    /* 3.Configurating PLL Clock Divider Ratio                          */
    /*   (1) Set the following registers: R#01h: PLLR[4:0],             */
    /*                                    R#01h-#02h: PLLF[8:0].        */
    /*   (2) Write 1 into R#00h: SR to execute the software reset.      */
    /*       *The values specified with R#01h: PLLR[4:0]                */
    /*        and R#01h-#02h: PLLF[8:0] are used for the PLL operation. */
    /*   (3) Wait until P#2: INIEND becomes 1 which indicates PLL Reset */
    /*       Phase and PLL Lock-up Phase have completed.                */
    /*       *Reset Phase (256 x XIN clock cycles) takes                */
    /*        12.8us(at 20MHz) to 42.7us (at 6 MHz).                    */
    /*       *Lock-up Phase (20000 x XIN clock cycles) takes            */
    /*        1ms(at 20 MHz) to 3.4ms (at 6 MHz).                       */
    /*   (4) Read from the registers R#04h: RPLLR[4:0] and R#04h-#05h:  */
    /*       RPLLF[8:0] to confirm that their values match the value    */
    /*       written in the step (1).                                   */

    do
    {
      YGV642_Write_Reg_Pll(REG_R01H, tYvc1Data.Clk[0]);			    /* (1)	*/
      YGV642_Write_Reg_Pll(REG_R02H, tYvc1Data.Clk[1]);

      YGV642_Write_Reg_Pll(REG_R00H, YVC1_SR);			            /* (2)	*/

      YGV642_Wait_ms(YVC1_PLL_LOCKUP_WAIT);			                /* (3)	*/
      YGV642_INIEND_Wait_Polling();

      YGV642_Read_Reg(REG_R04H, &PLLReg[0]);							      /* (4)	*/
      YGV642_Read_Reg(REG_R05H, &PLLReg[1]);
    }
    while ((PLLReg[0] != tYvc1Data.Clk[0]) || (PLLReg[1] != tYvc1Data.Clk[1]));

    /* 4.Reconfiguration Registers                                      */
    /*   (1) Set Clock Control register (R#03h).                        */
    /*   (2) Set Display Scan Control register (R#06h-#1Ch).            */
    /*       (*To use the timing controller function,                   */
    /*         set Timing Controller register (R#67h-#7Dh).             */
    
    YGV642_Write_Reg(REG_R03H, tYvc1Data.Clk[2]);               /* (1)	*/
    
    YGV642_Write_Regs(REG_R06H, tYvc1Data.Disp, 23);            /* (2)	*/
	  YGV642_Write_Reg(REG_R31H, tYvc1Data.VideoOut);
    YGV642_Write_Regs(REG_R67H, tYvc1Data.TCON, 23);
  }
  
  /*----------------------------------------------------------------------*/
  /* R#55h-R#5Bh pattern memory control setup                             */
  /* Set the YVC1_PmemSet() processing according to use environment.      */
  /*----------------------------------------------------------------------*/
  #pragma MESSAGE DISABLE C1801
  #pragma MESSAGE DISABLE C1420
  YGV642_Pattern_Memory_Init();
  
  /*----------------------------------------------------------------------*/
  /* Set automatic address increment                                      */
  /*----------------------------------------------------------------------*/
  YGV642_Write_Reg(REG_R27H, 0x07);
  
  /*----------------------------------------------------------------------*/
  /* General table Init                                                   */
  /*----------------------------------------------------------------------*/
  #if YVC_GENERAL_TABLE_INIT
    YGV642_General_Table_Init();
  #endif
  
  /*----------------------------------------------------------------------*/
  /* Set the extended layer function and the size of alpha values         */
  /*----------------------------------------------------------------------*/
  YGV642_Read_Reg(REG_R30H, &tY642R30H.BYTE);
  tY642R30H.BIT.EXLY    = 0;
  tY642R30H.BIT.ALPBSEL = 1;	
  YGV642_Write_Reg(REG_R30H, tY642R30H.BYTE);
  
  /*----------------------------------------------------------------------*/
  /* Set Host Controlled Layer Registers                                  */
  /*----------------------------------------------------------------------*/
  YGV642_Read_Reg(REG_R3EH, &tY642R3EH.BYTE);

  #pragma MESSAGE DISABLE C4001
  if(YVC_LYR_NUM_CPU == 0)
  {
    tY642R3EH.BIT.LYDC = 0;
    YGV642_Write_Reg(REG_R3EH, tY642R3EH.BYTE);
  }
  else
  {
    tY642R3FH.BYTE = 0;
    tY642R40H.BYTE = 0;
    tY642R41H.BYTE = 0;
    
    LyrEndAddr     = YVC_LYR_ADDR_CPU + (YVC_LYR_NUM_CPU - 1) * YVC1_LYR_SIZE;
    
    tY642R3EH.BIT.LYSAC_8 = ((YVC_LYR_ADDR_CPU >> SHIFT_08BIT) & MASK_0FH);
    tY642R3FH.BIT.LYSAC_2 = ((YVC_LYR_ADDR_CPU >> SHIFT_02BIT) & MASK_3FH);
    tY642R40H.BIT.LYEAC_8 = ((LyrEndAddr       >> SHIFT_08BIT) & MASK_0FH);
    tY642R41H.BIT.LYEAC_2 = ((LyrEndAddr       >> SHIFT_02BIT) & MASK_3FH);
    
    YGV642_Write_Reg(REG_R3EH, tY642R3EH.BYTE);
    YGV642_Write_Reg(REG_R3FH, tY642R3FH.BYTE);
    YGV642_Write_Reg(REG_R40H, tY642R40H.BYTE);
    YGV642_Write_Reg(REG_R41H, tY642R41H.BYTE);
  } 
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Set_Transparent_Color                              */
/* Contents         : Set Transparent Color                                     */
/* Argument         : uint8_t   ColorR    (W)color component red                */
/*                    uint8_t   ColorG    (W)color component green              */
/*                    uint8_t   ColorB    (W)color component blue               */  
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
void YGV642_Set_Transparent_Color(uint8_t ColorR, uint8_t ColorG, uint8_t ColorB)
{
  /*--- Transparent Color output ---*/
	YGV642_Write_Reg(REG_R49H, ColorR);		/* R color	*/		
	YGV642_Write_Reg(REG_R4AH, ColorG);		/* G color	*/
	YGV642_Write_Reg(REG_R4BH, ColorB);		/* B color	*/
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Set_Border_Color                                   */
/* Contents         : Set Border Color                                          */
/* Argument         : uint8_t   ColorR    (W)color component red                */
/*                    uint8_t   ColorG    (W)color component green              */
/*                    uint8_t   ColorB    (W)color component blue               */  
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
void YGV642_Set_Border_Color(uint8_t ColorR, uint8_t ColorG, uint8_t ColorB)
{
  /*--- Border Color output ---*/
	YGV642_Write_Reg(REG_R52H, ColorR);		/* R color	*/								
	YGV642_Write_Reg(REG_R53H, ColorG);		/* G color	*/
	YGV642_Write_Reg(REG_R54H, ColorB);		/* B color	*/ 
}

#if YVC_TEXT_LYR_ENABLE
/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Set_Text_Color_Palettes                            */
/* Contents         : Set Text Color Palettes                                   */
/* Argument         : uint8_t   *Buff;   (W)Write buffer pointer                */
/*                    uint16_t   Num;    (W)Number of bytes to write            */ 
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
void YGV642_Set_Text_Color_Palettes(const uint8_t *Buff, uint16_t Num)
{
  uint16_t i;
  
	/*--------------------------------------*/
	/*  Input Check                         */
	/*--------------------------------------*/
	if ((Buff == (const uint8_t *)NULL) || (Num == 0) || (Num >> 3) > YVC_TEXT_COLOR_NUM)
    return;

	/*--------------------------------------*/
	/*  Setup                               */
	/*--------------------------------------*/
  /*--- Color palette address set ---*/
  YGV642_Write_Reg(REG_R2AH, (uint8_t)(YVC_TEXT_PLT_ADDR >> SHIFT_08BIT)); 
  YGV642_Write_Reg(REG_R2BH, (uint8_t)(YVC_TEXT_PLT_ADDR &  MASK_FFH));
  
  /*--- Auto increment bit set ---*/
  YGV642_Write_Reg(REG_R27H, 0x07);	/* AICP=1	*/

  /*--- It writes pallette data in the auto increment ---*/
  for (i = 0; i < Num; i++)
    YGV642_Write_Port(Y642_PORT_PLT_DATA, Buff[i]);
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Set_Text_Fonts                                     */
/* Contents         : Set Text Fonts                                            */
/* Argument         : uint8_t   *Buff;   (W)Write buffer pointer                */
/*                    uint16_t   Num;    (W)Number of bytes to write            */ 
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
void YGV642_Set_Text_Fonts(const uint8_t *Buff, uint16_t Num)
{
  uint16_t i;
  
	/*--------------------------------------*/
	/*  Input Check                         */
	/*--------------------------------------*/
	if ((Buff == (const uint8_t *)NULL) || (Num == 0) || (Num >> 3) > YVC_TBL_FONT_NUM)
    return;

	/*--------------------------------------*/
	/*      Set Font Type Attribute Data    */
	/*--------------------------------------*/
  
  /*--- Auto increment bit set ---*/
  YGV642_Write_Reg(REG_R27H, 0x07);	/* AICP=1	*/
  
  /*--- General table1 address set ---*/
  YGV642_Write_Reg(REG_R28H, (uint8_t)(YVC_TBL_FONT_ADDR >> SHIFT_08BIT));
  YGV642_Write_Reg(REG_R29H, (uint8_t)(YVC_TBL_FONT_ADDR &  MASK_FFH));
  
  /*--- Birst Write ---*/
  for (i = 0; i < Num; i++)
    YGV642_Write_Port(Y642_PORT_GENTBL_DATA, Buff[i]);  

  /*--- General table2 address set ---*/
  YGV642_Write_Reg(REG_R28H, (uint8_t)((YVC_TBL_FONT_ADDR | YVC1_DOUBLE_BUFF_ADDR) >> SHIFT_08BIT));
  YGV642_Write_Reg(REG_R29H, (uint8_t)((YVC_TBL_FONT_ADDR | YVC1_DOUBLE_BUFF_ADDR) &  MASK_FFH));
  
  /*--- Birst Write ---*/
  for (i = 0; i < Num; i++)
    YGV642_Write_Port(Y642_PORT_GENTBL_DATA, Buff[i]); 
}
#endif

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Enable_Host_Controlled_Layer                       */
/* Contents         : Enable Host Controlled Layer                              */
/* Argument         : void                                                      */
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
void YGV642_Enable_Host_Controlled_Layer(void)
{
  T_Y642_R3EH tY642R3EH;
  
  YGV642_Read_Reg(REG_R3EH, &tY642R3EH.BYTE);

  if(tY642R3EH.BIT.LYDC == 0)
  {
    tY642R3EH.BIT.LYDC = 1;
    YGV642_Write_Reg(REG_R3EH, tY642R3EH.BYTE);
  }
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Get_Updateable_Table                               */
/* Contents         : Get the updateable general table.                         */
/* Argument         : void                                                      */
/*                                                                              */
/* Return value     : Updateable General Table: YVC1_GENERAL_TABLE1             */
/*                                              YVC1_GENERAL_TABLE2             */
/*------------------------------------------------------------------------------*/
uint16_t YGV642_Get_Updateable_Table(void)
{
	uint8_t   Reg3EHData;
  uint16_t  UpdateableTable;

	YGV642_Read_Reg(REG_R3EH, &Reg3EHData);
	
	if ((Reg3EHData & YVC1_LYBSELC_MASK) != YVC1_LYBSELC_TBL1)
    UpdateableTable = YVC1_GENERAL_TABLE2;
	else
    UpdateableTable = YVC1_GENERAL_TABLE1;
	
  return UpdateableTable;
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Flip_Table                                         */
/* Contents         : Flip General Table and return the updateable table.       */
/*                    There are 2 general tables in YGV642. One of the          */   
/*                    alternative General Table will be used for display        */
/*                    rendering while the other is updated by the host. Calling */ 
/*                    this function causes the switch between the two general   */
/*                    table and the updateable one will be return.              */
/* Argument         : void                                                      */
/*                                                                              */
/* Return value     : Updateable General Table: YVC1_GENERAL_TABLE1             */
/*                                              YVC1_GENERAL_TABLE2             */
/*------------------------------------------------------------------------------*/
uint16_t YGV642_Flip_Table(void)
{
	uint8_t   Reg3EHData;
	uint8_t   Reg3FHData;
	uint8_t   Reg40HData;
	uint8_t   Reg41HData;
  
  uint16_t  UpdateableTable;
  
  T_Y642_PORT_FLAG1 tY642PortFlag1;

	YGV642_Read_Reg(REG_R3EH, &Reg3EHData);
	YGV642_Read_Reg(REG_R3FH, &Reg3FHData);
	YGV642_Read_Reg(REG_R40H, &Reg40HData);
	YGV642_Read_Reg(REG_R41H, &Reg41HData);
  
	if ((Reg3EHData & YVC1_LYBSELC_MASK) != YVC1_LYBSELC_TBL1)
  {
    /*--- Flip General Table 1 ---*/
    #pragma MESSAGE DISABLE C2705
		Reg3EHData &= (uint8_t)(~YVC1_LYBSELC_MASK);
    UpdateableTable = YVC1_GENERAL_TABLE2;
  }
	else
  {
    /*--- Flip General Table 2 ---*/
		Reg3EHData |= (uint8_t)(YVC1_LYBSELC_MASK);
    UpdateableTable = YVC1_GENERAL_TABLE1;
  }
  
	YGV642_Write_Reg(REG_R3EH, Reg3EHData);
	YGV642_Write_Reg(REG_R3FH, Reg3FHData);
	YGV642_Write_Reg(REG_R40H, Reg40HData);
	YGV642_Write_Reg(REG_R41H, Reg41HData);
  
  /*--- P#6 FB flag reset ---*/
  tY642PortFlag1.BYTE = 0;
  tY642PortFlag1.BIT.FB = 1;
	YGV642_Write_Port(YVC1_PORT_FLG_STATUS1, tY642PortFlag1.BYTE);
  
  return UpdateableTable;
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Get_Table_Flip_Status                              */
/* Contents         : Get general table flipping status                         */
/* Argument         : void                                                      */
/* Return value     : YVC1_TBL_FLIP_COMPLETE or YVC1_TBL_FLIP_NOT_COMPLETE      */
/*------------------------------------------------------------------------------*/
uint8_t YGV642_Get_Table_Flip_Status(void)
{
  T_Y642_PORT_FLAG1 tY642PortFlag1;
  
  tY642PortFlag1.BYTE = YGV642_Read_Port(Y642_PORT_FLG_STATUS1);
  
  if (tY642PortFlag1.BIT.FB)
    return YVC1_TBL_FLIP_COMPLETE;
  else 
    return YVC1_TBL_FLIP_NOT_COMPLETE;
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Calc_Pattern_Memory_CheckSum                       */
/* Contents         : Calculate Pattern Memory Checksums                        */
/* Argument         : uint32_t  StartAddr (W)checksum start address             */
/*                    uint32_t  EndAddr   (W)checksum end address               */
/*                                                                              */
/* Return value     : Checksum                                                  */
/*------------------------------------------------------------------------------*/
uint16_t YGV642_Calc_Pattern_Memory_CheckSum(uint32_t StartAddr, uint32_t EndAddr)
{
	uint16_t CheckSum;
  uint8_t  Data;
	
	/*--- set start address ---*/
	Data = (uint8_t)((StartAddr >> SHIFT_24BIT) & MASK_03H);
	YGV642_Write_Reg(REG_R34H, Data);
	Data = (uint8_t)((StartAddr >> SHIFT_16BIT) & MASK_FFH);
	YGV642_Write_Reg(REG_R35H, Data);
	Data = (uint8_t)((StartAddr >> SHIFT_08BIT) & MASK_FFH);
	YGV642_Write_Reg(REG_R36H, Data);
	Data = (uint8_t) (StartAddr                 & MASK_FFH);
	YGV642_Write_Reg(REG_R37H, Data);
	
	/*--- set end address ---*/
	Data = (uint8_t)((EndAddr >> SHIFT_24BIT) & MASK_03H);
	YGV642_Write_Reg(REG_R38H, Data);
	Data = (uint8_t)((EndAddr >> SHIFT_16BIT) & MASK_FFH);
	YGV642_Write_Reg(REG_R39H, Data);
	Data = (uint8_t)((EndAddr >> SHIFT_08BIT) & MASK_FFH);
	YGV642_Write_Reg(REG_R3AH, Data);
	Data = (uint8_t) (EndAddr                 & MASK_FFH);
	YGV642_Write_Reg(REG_R3BH, Data);
	
	/*--- Check Sum Start ---*/
	YGV642_Write_Reg(REG_R33H, 1);
	do
	{
    wdt_reset();
		YGV642_Read_Reg(REG_R33H, &Data);
	} while(Data == 1);

	/*--- Get Check Sum ---*/
	YGV642_Read_Reg(REG_R3DH, &Data);
	CheckSum = (uint16_t)Data;
	YGV642_Read_Reg(REG_R3CH, &Data);
	CheckSum = ((uint16_t)Data << 8) | CheckSum;
	
	return CheckSum;
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_General_Table_Init                 (Sub Function)  */
/* Contents         : General table Init                                        */
/* Argument         : void                                                      */
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
#if YVC_GENERAL_TABLE_INIT
void YGV642_General_Table_Init(void)
{
  uint8_t         i;
	uint16_t        Addr;
  uint16_t        TableAddr;
	const uint8_t   YvcLyrAttrData[YVC1_LYR_SIZE] = SET_LYR_ERASE_ATTR_DEF; 
  
	/*--- General table Init   ---*/
	for (Addr = YVC_LYR_ADDR_CPU; Addr < YVC_LYR_ADDR_CPU + (YVC1_LYR_SIZE * YVC_LYR_NUM_CPU); Addr += YVC1_LYR_SIZE)   //YVC1_GTBL_BUFF_LOOP_SIZE
	{
    /*--- General table 1 init ---*/
    TableAddr = Addr;
    
    YGV642_Write_Reg(REG_R28H, (uint8_t)(TableAddr >> SHIFT_08BIT));
    YGV642_Write_Reg(REG_R29H, (uint8_t)(TableAddr & MASK_FFH));
    
    for (i = 0; i < YVC1_LYR_SIZE; i++) 
      YGV642_Write_Port(Y642_PORT_GENTBL_DATA, YvcLyrAttrData[i]);
    
    /*--- General table 2 init ---*/
    TableAddr = Addr + YVC1_DOUBLE_BUFF_ADDR;
    
    YGV642_Write_Reg(REG_R28H, (uint8_t)(TableAddr >> SHIFT_08BIT));
    YGV642_Write_Reg(REG_R29H, (uint8_t)(TableAddr & MASK_FFH));
    
    for (i = 0; i < YVC1_LYR_SIZE; i++) 
      YGV642_Write_Port(Y642_PORT_GENTBL_DATA, YvcLyrAttrData[i]);
	}
}
#endif

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Write_Reg                                          */
/* Contents         : Register 1-byte write                                     */
/* Argument         : uint8_t   RegNo   (W)Register number                      */
/*                  : uint8_t   Data    (W)Write data                           */
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
void YGV642_Write_Reg(uint8_t RegNo, uint8_t Data)
{
  /*--- Register data set ---*/
  YGV642_Write_Port(YVC1_PORT_REG_SEL, RegNo);
  YGV642_Write_Port(YVC1_PORT_REG_DATA, Data);
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Write_Reg_Pll                                      */
/* Contents         : Pll Register 1-byte write                                 */
/* Argument         : uint8_t   RegNo   (W)Register number                      */
/*                  : uint8_t   Data    (W)Write data                           */
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
void YGV642_Write_Reg_Pll(uint8_t RegNo, uint8_t Data)
{
  YGV642_Write_Port(YVC1_PORT_REG_SEL, RegNo);
  YGV642_Wait_ms(1);
  
  YGV642_Write_Port(YVC1_PORT_REG_DATA, Data);
  YGV642_Wait_ms(1);
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Write_Regs                                         */
/* Contents         : Register continuous write                                 */
/* Argument         : uint8_t   RegNo;  (W)Start register number                */
/*                    uint8_t   *Buff;  (W)Write buffer pointer                 */
/*                    uint8_t   Num;    (W)Number of bytes to write             */
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
void YGV642_Write_Regs(uint8_t RegNo, const uint8_t *Buff, uint8_t Num)
{
  uint8_t i;
	uint8_t PortRegSel;
  
  /*--- Auto increment bit set ---*/
  PortRegSel = RegNo | YVC1REG_AIRG;				/* AIRG=1	*/
  YGV642_Write_Port(YVC1_PORT_REG_SEL, PortRegSel);

  /*--- It writes register data in the auto increment ---*/
  for (i = 0; i < Num; i++)
    YGV642_Write_Port(YVC1_PORT_REG_DATA, Buff[i]);
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Read_Reg                                           */
/* Contents         : Register 1-byte read                                      */
/* Argument         : uint8_t   RegNo   (W)Register number                      */
/*                    uint8_t   *Data   (R)Read data pointer                    */
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
void YGV642_Read_Reg(uint8_t RegNo, uint8_t *Data)
{
  /*--- Register data set ---*/
  YGV642_Write_Port(YVC1_PORT_REG_SEL, RegNo);
  *Data = YGV642_Read_Port(YVC1_PORT_REG_DATA);
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_INIEND_Wait_Polling                (Sub Function)  */
/* Contents         : Initialization completion status(INIEND) polling          */
/* Argument         : void                                                      */
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
void YGV642_INIEND_Wait_Polling(void)
{
	/*--- INIEND polling 	---*/
  while ((YGV642_Read_Port(YVC1_PORT_PTNMEM_READACS) & YVC1_INIEND_CHK) == 0)
    YGV642_Wait_ms(YVC1_INIEND_WAIT);
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Write_Port                                         */
/* Contents         : Transmit data to specified port                           */
/* Argument         : uint8_t   Port    (W)Port name                            */
/*                    uint8_t   Data    (W)Data to be transmitted               */
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
void YGV642_Write_Port(uint8_t Port, uint8_t Data)
{
  uint16_t  TxData;

	Port    &= 0x07;         
	TxData   = (uint16_t)Data;
	TxData <<= 8;
	TxData  |= Port;
  
  YGV642_SPI_nCS_Low();
  
  YGV642_SPI_Word_Write(TxData);

  YGV642_SPI_nCS_High();
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Read_Port                                          */
/* Contents         : Get data from specified port                              */
/* Argument         : uint8_t   Port    (W)Port name                            */
/*                                                                              */
/* Return value     : Received data                                             */
/*------------------------------------------------------------------------------*/
uint8_t YGV642_Read_Port(uint8_t Port)
{
  uint8_t  RxData;
  
	Port |= 0x08;

  YGV642_SPI_nCS_Low();
  
  YGV642_SPI_Byte_Write(Port);
  RxData = YGV642_SPI_Byte_Read();

  YGV642_SPI_nCS_High();

	return RxData;
}

/*------------------------------------------------------------------------------*/
/* Function name    : YGV642_Wait_ms                                            */
/* Contents         : msec timer wait function                                  */
/* Argument         : uint8_t msCnt    (W) How many ms to wait                  */
/*                                                                              */
/* Return value     : void                                                      */
/*------------------------------------------------------------------------------*/
void YGV642_Wait_ms(uint8_t msCnt)
{
  uint16_t Dst;
  
  Dst  = (uint16_t)msCnt;
  Dst  = Dst * (1024 / API_INT_CYCLE);
  Dst += API_ROLLING_COUNTER;
  
  while (Dst != API_ROLLING_COUNTER);
}
