/******************************************************************************
文 件 名：BU98R10.c
功能描述：BU98R10段码液晶控制器驱动程序库文件
作    者：张暄
版    本：V1.0
日    期：2017.4.28
******************************************************************************/

#include "include.h"
#include "BU98R10.h"

#if   USE_BU98R10_CHIP_0
volatile BU98R10DDRAMUnion        BU98R10Chip0DDRAM;
BU98R10DDRAMUnion                 BU98R10Chip0DDRAMBackup;
#endif

#if   USE_BU98R10_CHIP_1
volatile BU98R10DDRAMUnion        BU98R10Chip1DDRAM;
BU98R10DDRAMUnion                 BU98R10Chip1DDRAMBackup;
#endif

#if   USE_BU98R10_CHIP_2
volatile BU98R10DDRAMUnion        BU98R10Chip2DDRAM;
BU98R10DDRAMUnion                 BU98R10Chip2DDRAMBackup;
#endif


/******************************************************************************
刷新控制结构定义
******************************************************************************/
typedef struct
{
  uint8_t En;
  uint8_t Chip;
  uint8_t Step;
  uint8_t Cont;
  uint8_t Addr;
}BU98R10UpdateCtrlStruct;

BU98R10UpdateCtrlStruct           BU98R10Update;

/******************************************************************************
函数名：BU98R10_Init
功  能：初始化BU98R10
参  数：无
返回值：无
******************************************************************************/
void BU98R10_Init(void)
{
  uint8_t i;
  
  #if     BU98R10_WRITE_AT_SAME_TIME
    #if   BU98R10_COLORFUL_LCD_MODE
    
      //软件复位
      BU98R10_All_Command_Write(BU98R10_CMD_SWRST);
      
      //工作模式
      BU98R10_All_Command_Write(BU98R10_CMD_ICSET | BU98R10_PAR_ICSET_RGB);
      
      //驱动控制
      BU98R10_All_Command_Write(BU98R10_CMD_DRVCTRL | BU98R10_PAR_DRVCTRL_NORMAL);
      
      //帧刷新率
      BU98R10_All_Command_Write(BU98R10_CMD_FREQ);
      BU98R10_All_Data_Write(BU98R10_FRAME_FREQ, BU98R10_FRAME_FREQ, BU98R10_FRAME_FREQ); 
    
      //色彩设置
      BU98R10_All_Command_Write(BU98R10_CMD_LED_CTRL);
      BU98R10_All_Data_Write(0x12, 0x12, 0x12); 
    
      BU98R10_All_Command_Write(BU98R10_CMD_SEG_R);
      BU98R10_All_Data_Write(BU98R10_REG_SEG_R, BU98R10_REG_SEG_R, BU98R10_REG_SEG_R); 
    
      BU98R10_All_Command_Write(BU98R10_CMD_SEG_G);
      BU98R10_All_Data_Write(BU98R10_REG_SEG_G, BU98R10_REG_SEG_G, BU98R10_REG_SEG_G);   
    
      BU98R10_All_Command_Write(BU98R10_CMD_SEG_B);
      BU98R10_All_Data_Write(BU98R10_REG_SEG_B, BU98R10_REG_SEG_B, BU98R10_REG_SEG_B);   
    
      BU98R10_All_Command_Write(BU98R10_CMD_LED_STARTR);
      BU98R10_All_Data_Write(BU98R10_LRS, BU98R10_LRS, BU98R10_LRS);   
    
      BU98R10_All_Command_Write(BU98R10_CMD_LED_STARTG);
      BU98R10_All_Data_Write(BU98R10_LGS, BU98R10_LGS, BU98R10_LGS);  
      
      BU98R10_All_Command_Write(BU98R10_CMD_LED_STARTB);
      BU98R10_All_Data_Write(BU98R10_LBS, BU98R10_LBS, BU98R10_LBS);  
      
      BU98R10_All_Command_Write(BU98R10_CMD_LED_WIDTHR);
      BU98R10_All_Data_Write(BU98R10_LRW, BU98R10_LRW, BU98R10_LRW);
      
      BU98R10_All_Command_Write(BU98R10_CMD_LED_WIDTHG);
      BU98R10_All_Data_Write(BU98R10_LGW, BU98R10_LGW, BU98R10_LGW);
      
      BU98R10_All_Command_Write(BU98R10_CMD_LED_WIDTHB);
      BU98R10_All_Data_Write(BU98R10_LBW, BU98R10_LBW, BU98R10_LBW);

      //清除RAM数据    
      BU98R10_All_Command_Write(BU98R10_CMD_ADSET);
      BU98R10_All_Data_Write(0x00, 0x00, 0x00);
      
      BU98R10_All_Command_Write(BU98R10_CMD_DATWR);
      for (i = 0; i < 90; i++)
        BU98R10_All_Data_Write(BU98R10_DEFAULT_BYTE, BU98R10_DEFAULT_BYTE, BU98R10_DEFAULT_BYTE);
      
      for (i = 0; i < BU98R10_DDRAM_SIZE; i++)
      {
        BU98R10Chip0DDRAM.Byte[i] = BU98R10_DEFAULT_BYTE;
        BU98R10Chip0DDRAMBackup.Byte[i] = BU98R10_DEFAULT_BYTE;
        
        BU98R10Chip1DDRAM.Byte[i] = BU98R10_DEFAULT_BYTE;
        BU98R10Chip1DDRAMBackup.Byte[i] = BU98R10_DEFAULT_BYTE;
        
        BU98R10Chip2DDRAM.Byte[i] = BU98R10_DEFAULT_BYTE;
        BU98R10Chip2DDRAMBackup.Byte[i] = BU98R10_DEFAULT_BYTE;
      }
      
      //开显示
      BU98R10_All_Command_Write(BU98R10_CMD_DISPON);
      
    #else
      
      //软件复位
      BU98R10_All_Command_Write(BU98R10_CMD_SWRST);
      
      //工作模式
      BU98R10_All_Command_Write(BU98R10_CMD_ICSET | BU98R10_PAR_ICSET_MONO);
      
      //驱动控制
      BU98R10_All_Command_Write(BU98R10_CMD_DRVCTRL | BU98R10_PAR_DRVCTRL_NORMAL);
      
      //帧刷新率
      BU98R10_All_Command_Write(BU98R10_CMD_FREQ);
      BU98R10_All_Data_Write(BU98R10_FRAME_FREQ, BU98R10_FRAME_FREQ, BU98R10_FRAME_FREQ); 
      
      //清除RAM数据    
      BU98R10_All_Command_Write(BU98R10_CMD_ADSET);
      BU98R10_All_Data_Write(0x00, 0x00, 0x00);
      
      BU98R10_All_Command_Write(BU98R10_CMD_DATWR);
      for (i = 0; i < 90; i++)
        BU98R10_All_Data_Write(BU98R10_DEFAULT_BYTE, BU98R10_DEFAULT_BYTE, BU98R10_DEFAULT_BYTE);
      
      for (i = 0; i < BU98R10_DDRAM_SIZE; i++)
      {
        BU98R10Chip0DDRAM.Byte[i] = BU98R10_DEFAULT_BYTE;
        BU98R10Chip0DDRAMBackup.Byte[i] = BU98R10_DEFAULT_BYTE;
        
        BU98R10Chip1DDRAM.Byte[i] = BU98R10_DEFAULT_BYTE;
        BU98R10Chip1DDRAMBackup.Byte[i] = BU98R10_DEFAULT_BYTE;
        
        BU98R10Chip2DDRAM.Byte[i] = BU98R10_DEFAULT_BYTE;
        BU98R10Chip2DDRAMBackup.Byte[i] = BU98R10_DEFAULT_BYTE;
      }
      
      //开显示
      BU98R10_All_Command_Write(BU98R10_CMD_DISPON);
      
    #endif
  #else
    #if BU98R10_COLORFUL_LCD_MODE
      #if USE_BU98R10_CHIP_0
      
        //软件复位
        BU98R10_0_Command_Write(BU98R10_CMD_SWRST);
        
        //工作模式
        BU98R10_0_Command_Write(BU98R10_CMD_ICSET | BU98R10_PAR_ICSET_RGB);
        
        //驱动控制
        BU98R10_0_Command_Write(BU98R10_CMD_DRVCTRL | BU98R10_PAR_DRVCTRL_NORMAL);
        
        //帧刷新率
        BU98R10_0_Command_Write(BU98R10_CMD_FREQ);
        BU98R10_0_Data_Write(BU98R10_FRAME_FREQ); 
      
        //色彩设置
        BU98R10_0_Command_Write(BU98R10_CMD_LED_CTRL);
        BU98R10_0_Data_Write(0x12); 
      
        BU98R10_0_Command_Write(BU98R10_CMD_SEG_R);
        BU98R10_0_Data_Write(BU98R10_REG_SEG_R); 
      
        BU98R10_0_Command_Write(BU98R10_CMD_SEG_G);
        BU98R10_0_Data_Write(BU98R10_REG_SEG_G);   
      
        BU98R10_0_Command_Write(BU98R10_CMD_SEG_B);
        BU98R10_0_Data_Write(BU98R10_REG_SEG_B);   
      
        BU98R10_0_Command_Write(BU98R10_CMD_LED_STARTR);
        BU98R10_0_Data_Write(BU98R10_LRS);   
      
        BU98R10_0_Command_Write(BU98R10_CMD_LED_STARTG);
        BU98R10_0_Data_Write(BU98R10_LGS);  
        
        BU98R10_0_Command_Write(BU98R10_CMD_LED_STARTB);
        BU98R10_0_Data_Write(BU98R10_LBS);  
        
        BU98R10_0_Command_Write(BU98R10_CMD_LED_WIDTHR);
        BU98R10_0_Data_Write(BU98R10_LRW);
        
        BU98R10_0_Command_Write(BU98R10_CMD_LED_WIDTHG);
        BU98R10_0_Data_Write(BU98R10_LGW);
        
        BU98R10_0_Command_Write(BU98R10_CMD_LED_WIDTHB);
        BU98R10_0_Data_Write(BU98R10_LBW);

        //清除RAM数据    
        BU98R10_0_Command_Write(BU98R10_CMD_ADSET);
        BU98R10_0_Data_Write(0x00);
        
        BU98R10_0_Command_Write(BU98R10_CMD_DATWR);
        for (i = 0; i < 90; i++)
          BU98R10_0_Data_Write(BU98R10_DEFAULT_BYTE);
        
        for (i = 0; i < BU98R10_DDRAM_SIZE; i++)
        {
          BU98R10Chip0DDRAM.Byte[i] = BU98R10_DEFAULT_BYTE;
          BU98R10Chip0DDRAMBackup.Byte[i] = BU98R10_DEFAULT_BYTE;
        }
        
        //开显示
        BU98R10_0_Command_Write(BU98R10_CMD_DISPON);
        
      #endif
      #if USE_BU98R10_CHIP_1
      
        //软件复位
        BU98R10_1_Command_Write(BU98R10_CMD_SWRST);
        
        //工作模式
        BU98R10_1_Command_Write(BU98R10_CMD_ICSET | BU98R10_PAR_ICSET_RGB);
        
        //驱动控制
        BU98R10_1_Command_Write(BU98R10_CMD_DRVCTRL | BU98R10_PAR_DRVCTRL_NORMAL);
        
        //帧刷新率
        BU98R10_1_Command_Write(BU98R10_CMD_FREQ);
        BU98R10_1_Data_Write(BU98R10_FRAME_FREQ); 
      
        //色彩设置
        BU98R10_1_Command_Write(BU98R10_CMD_LED_CTRL);
        BU98R10_1_Data_Write(0x12); 
      
        BU98R10_1_Command_Write(BU98R10_CMD_SEG_R);
        BU98R10_1_Data_Write(BU98R10_REG_SEG_R); 
      
        BU98R10_1_Command_Write(BU98R10_CMD_SEG_G);
        BU98R10_1_Data_Write(BU98R10_REG_SEG_G);   
      
        BU98R10_1_Command_Write(BU98R10_CMD_SEG_B);
        BU98R10_1_Data_Write(BU98R10_REG_SEG_B);   
      
        BU98R10_1_Command_Write(BU98R10_CMD_LED_STARTR);
        BU98R10_1_Data_Write(BU98R10_LRS);   
      
        BU98R10_1_Command_Write(BU98R10_CMD_LED_STARTG);
        BU98R10_1_Data_Write(BU98R10_LGS);  
        
        BU98R10_1_Command_Write(BU98R10_CMD_LED_STARTB);
        BU98R10_1_Data_Write(BU98R10_LBS);  
        
        BU98R10_1_Command_Write(BU98R10_CMD_LED_WIDTHR);
        BU98R10_1_Data_Write(BU98R10_LRW);
        
        BU98R10_1_Command_Write(BU98R10_CMD_LED_WIDTHG);
        BU98R10_1_Data_Write(BU98R10_LGW);
        
        BU98R10_1_Command_Write(BU98R10_CMD_LED_WIDTHB);
        BU98R10_1_Data_Write(BU98R10_LBW);

        //清除RAM数据    
        BU98R10_1_Command_Write(BU98R10_CMD_ADSET);
        BU98R10_1_Data_Write(0x00);
        
        BU98R10_1_Command_Write(BU98R10_CMD_DATWR);
        for (i = 0; i < 90; i++)
          BU98R10_1_Data_Write(BU98R10_DEFAULT_BYTE);
        
        for (i = 0; i < BU98R10_DDRAM_SIZE; i++)
        {
          BU98R10Chip1DDRAM.Byte[i] = BU98R10_DEFAULT_BYTE;
          BU98R10Chip1DDRAMBackup.Byte[i] = BU98R10_DEFAULT_BYTE;
        }
        
        //开显示
        BU98R10_1_Command_Write(BU98R10_CMD_DISPON);
        
      #endif
    #else
      #if USE_BU98R10_CHIP_0
      
        //软件复位
        BU98R10_0_Command_Write(BU98R10_CMD_SWRST);
        
        //工作模式
        BU98R10_0_Command_Write(BU98R10_CMD_ICSET | BU98R10_PAR_ICSET_MONO);
        
        //驱动控制
        BU98R10_0_Command_Write(BU98R10_CMD_DRVCTRL | BU98R10_PAR_DRVCTRL_NORMAL);
        
        //帧刷新率
        BU98R10_0_Command_Write(BU98R10_CMD_FREQ);
        BU98R10_0_Data_Write(BU98R10_FRAME_FREQ);
        
        //清除RAM数据    
        BU98R10_0_Command_Write(BU98R10_CMD_ADSET);
        BU98R10_0_Data_Write(0x00);
        
        BU98R10_0_Command_Write(BU98R10_CMD_DATWR);
        for (i = 0; i < 90; i++)
          BU98R10_0_Data_Write(BU98R10_DEFAULT_BYTE);
        
        for (i = 0; i < BU98R10_DDRAM_SIZE; i++)
        {
          BU98R10Chip0DDRAM.Byte[i] = BU98R10_DEFAULT_BYTE;
          BU98R10Chip0DDRAMBackup.Byte[i] = BU98R10_DEFAULT_BYTE;
        }
        
        //开显示
        BU98R10_0_Command_Write(BU98R10_CMD_DISPON);
        
      #endif      
      #if USE_BU98R10_CHIP_1
      
        //软件复位
        BU98R10_1_Command_Write(BU98R10_CMD_SWRST);
        
        //工作模式
        BU98R10_1_Command_Write(BU98R10_CMD_ICSET | BU98R10_PAR_ICSET_MONO);
        
        //驱动控制
        BU98R10_1_Command_Write(BU98R10_CMD_DRVCTRL | BU98R10_PAR_DRVCTRL_NORMAL);
        
        //帧刷新率
        BU98R10_1_Command_Write(BU98R10_CMD_FREQ);
        BU98R10_1_Data_Write(BU98R10_FRAME_FREQ);
        
        //清除RAM数据    
        BU98R10_1_Command_Write(BU98R10_CMD_ADSET);
        BU98R10_1_Data_Write(0x00);
        
        BU98R10_1_Command_Write(BU98R10_CMD_DATWR);
        for (i = 0; i < 90; i++)
          BU98R10_1_Data_Write(BU98R10_DEFAULT_BYTE);

        for (i = 0; i < BU98R10_DDRAM_SIZE; i++)
        {
          BU98R10Chip1DDRAM.Byte[i] = BU98R10_DEFAULT_BYTE;
          BU98R10Chip1DDRAMBackup.Byte[i] = BU98R10_DEFAULT_BYTE;
        }
        
        //开显示
        BU98R10_1_Command_Write(BU98R10_CMD_DISPON);
        
      #endif 
    #endif
  #endif
  
  BU98R10Update.En   = 0;
  BU98R10Update.Step = 0;
  BU98R10Update.Cont = 0;
  BU98R10Update.Addr = 0;
  
  #if    USE_BU98R10_CHIP_0
    BU98R10Update.Chip = 0;
  #elif  USE_BU98R10_CHIP_1
    BU98R10Update.Chip = 1;
  #else
    BU98R10Update.Chip = 255;
  #endif
}

/******************************************************************************
函数名：BU98R10_Shutdown
功  能：关闭BU98R10显示,使其进入低功耗模式
参  数：无
返回值：无
******************************************************************************/
void BU98R10_Shutdown(void)
{
  #if     BU98R10_WRITE_AT_SAME_TIME
    BU98R10_All_Command_Write(BU98R10_CMD_DISPOFF);
  #else
    #if USE_BU98R10_CHIP_0
      BU98R10_0_Command_Write(BU98R10_CMD_DISPOFF);
    #endif
    
    #if USE_BU98R10_CHIP_1
      BU98R10_1_Command_Write(BU98R10_CMD_DISPOFF);
    #endif
  #endif
}

/******************************************************************************
函数名：BU98R10_Update_Request
功  能：请求刷新BU98R10的段码显示
参  数：无
返回值：无
******************************************************************************/
void BU98R10_Update_Request(void)
{
  BU98R10Update.En = 1;
  
  #if    USE_BU98R10_CHIP_0
    BU98R10Update.Chip = 0;
  #elif  USE_BU98R10_CHIP_1
    BU98R10Update.Chip = 1;
  #elif  USE_BU98R10_CHIP_2
    BU98R10Update.Chip = 2;
  #else
    BU98R10Update.Chip = 255;
  #endif  
}

/******************************************************************************
函数名：BU98R10_Update_Service
功  能：BU98R10段码显示刷新服务
参  数：无
返回值：无
*******************************************************************************
注  意：该服务函数必须每于系统空闲时实时调用
******************************************************************************/
void BU98R10_Update_Service(void)
{
  if (BU98R10Update.En)
  {
    #if BU98R10_WRITE_AT_SAME_TIME
    
    switch (BU98R10Update.Step)
    {
      case 0  : //检查DDRAM中当前字节是否需要更新
                if ((BU98R10Chip0DDRAM.Byte[BU98R10Update.Addr] != BU98R10Chip0DDRAMBackup.Byte[BU98R10Update.Addr]) || \
                    (BU98R10Chip1DDRAM.Byte[BU98R10Update.Addr] != BU98R10Chip1DDRAMBackup.Byte[BU98R10Update.Addr]) || \
                    (BU98R10Chip2DDRAM.Byte[BU98R10Update.Addr] != BU98R10Chip2DDRAMBackup.Byte[BU98R10Update.Addr]))
                {
                  BU98R10Chip0DDRAMBackup.Byte[BU98R10Update.Addr] = BU98R10Chip0DDRAM.Byte[BU98R10Update.Addr];
                  BU98R10Chip1DDRAMBackup.Byte[BU98R10Update.Addr] = BU98R10Chip1DDRAM.Byte[BU98R10Update.Addr];
                  BU98R10Chip2DDRAMBackup.Byte[BU98R10Update.Addr] = BU98R10Chip2DDRAM.Byte[BU98R10Update.Addr];
                  
                  if (BU98R10Update.Cont)
                    BU98R10Update.Step = 4;
                  else
                    BU98R10Update.Step = 1;
                }
                else
                {
                  BU98R10Update.Cont = 0;
                  BU98R10Update.Addr++;
                  if (BU98R10Update.Addr >= BU98R10_DDRAM_SIZE)
                  {
                    BU98R10Update.Addr = 0;
                    BU98R10Update.En   = 0;
                  }
                }
                break;
                
      case 1  : //请求写地址
                BU98R10_All_Command_Write(BU98R10_CMD_ADSET);
                BU98R10Update.Step = 2;
                break;
                
      case 2  : //写入地址
                #if BU98R10_COLORFUL_LCD_MODE
                  BU98R10_All_Data_Write(BU98R10Update.Addr, BU98R10Update.Addr, BU98R10Update.Addr);
                #else
                  BU98R10_All_Data_Write(BU98R10Update.Addr * 4, BU98R10Update.Addr * 4, BU98R10Update.Addr * 4);
                #endif
                BU98R10Update.Step = 3;
                break;
      
      case 3  : //请求写数据
                BU98R10_All_Command_Write(BU98R10_CMD_DATWR);
                BU98R10Update.Step = 4;
                break;
                
      case 4  : //写入数据
                BU98R10_All_Data_Write(BU98R10Chip0DDRAMBackup.Byte[BU98R10Update.Addr], BU98R10Chip1DDRAMBackup.Byte[BU98R10Update.Addr], BU98R10Chip2DDRAMBackup.Byte[BU98R10Update.Addr]);
                BU98R10Update.Step = 5;
                break;
                
      case 5  : //地址调整
                BU98R10Update.Addr++;
                if (BU98R10Update.Addr >= BU98R10_DDRAM_SIZE)
                {
                  BU98R10Update.Addr = 0;
                  BU98R10Update.En   = 0;
                  BU98R10Update.Cont = 0;
                }
                else                
                  BU98R10Update.Cont = 1;
                
                BU98R10Update.Step = 0;
                break;
                
      default : BU98R10Update.En   = 0;
                BU98R10Update.Step = 0;
                BU98R10Update.Cont = 0;
                BU98R10Update.Addr = 0;
                break;
    }

    #else
      
    #if  USE_BU98R10_CHIP_0
      
    if (BU98R10Update.Chip == 0)
    {
      switch (BU98R10Update.Step)
      {
        case 0  : //检查DDRAM中当前字节是否需要更新
                  if (BU98R10Chip0DDRAM.Byte[BU98R10Update.Addr] != BU98R10Chip0DDRAMBackup.Byte[BU98R10Update.Addr])
                  {
                    BU98R10Chip0DDRAMBackup.Byte[BU98R10Update.Addr] = BU98R10Chip0DDRAM.Byte[BU98R10Update.Addr];
                    
                    if (BU98R10Update.Cont)
                      BU98R10Update.Step = 4;
                    else
                      BU98R10Update.Step = 1;
                  }
                  else
                  {
                    BU98R10Update.Cont = 0;
                    BU98R10Update.Addr++;
                    if (BU98R10Update.Addr >= BU98R10_DDRAM_SIZE)
                    {
                      BU98R10Update.Addr = 0;
                      
                      #if  USE_BU98R10_CHIP_1
                        BU98R10Update.Chip = 1;
                      #else
                        BU98R10Update.En   = 0;
                      #endif
                    }
                  }
                  break;
                  
        case 1  : //请求写地址
                  BU98R10_0_Command_Write(BU98R10_CMD_ADSET);
                  BU98R10Update.Step = 2;
                  break;
                  
        case 2  : //写入地址
                  #if BU98R10_COLORFUL_LCD_MODE
                    BU98R10_0_Data_Write(BU98R10Update.Addr);
                  #else
                    BU98R10_0_Data_Write(BU98R10Update.Addr * 4);
                  #endif
                  BU98R10Update.Step = 3;
                  break;
        
        case 3  : //请求写数据
                  BU98R10_0_Command_Write(BU98R10_CMD_DATWR);
                  BU98R10Update.Step = 4;
                  break;
                  
        case 4  : //写入数据
                  BU98R10_0_Data_Write(BU98R10Chip0DDRAMBackup.Byte[BU98R10Update.Addr]);
                  BU98R10Update.Step = 5;
                  break;
                  
        case 5  : //地址调整
                  BU98R10Update.Addr++;
                  if (BU98R10Update.Addr >= BU98R10_DDRAM_SIZE)
                  {
                    BU98R10Update.Addr = 0;                    
                    BU98R10Update.Cont = 0;

                    #if  USE_BU98R10_CHIP_1
                      BU98R10Update.Chip = 1;
                    #else
                      BU98R10Update.En   = 0;
                    #endif
                  }
                  else                
                    BU98R10Update.Cont = 1;
                  
                  BU98R10Update.Step = 0;
                  break;
                  
        default : BU98R10Update.En   = 0;
                  BU98R10Update.Step = 0;
                  BU98R10Update.Cont = 0;
                  BU98R10Update.Addr = 0;
                  break;
      }
    }
    
    #if   USE_BU98R10_CHIP_1
    else if (BU98R10Update.Chip == 1)
    #endif
  
    #elif USE_BU98R10_CHIP_1
    if (BU98R10Update.Chip == 1)
    #endif
  
    #if   USE_BU98R10_CHIP_1
    {
      switch (BU98R10Update.Step)
      {
        case 0  : //检查DDRAM中当前字节是否需要更新
                  if (BU98R10Chip1DDRAM.Byte[BU98R10Update.Addr] != BU98R10Chip1DDRAMBackup.Byte[BU98R10Update.Addr])
                  {
                    BU98R10Chip1DDRAMBackup.Byte[BU98R10Update.Addr] = BU98R10Chip1DDRAM.Byte[BU98R10Update.Addr];
                    
                    if (BU98R10Update.Cont)
                      BU98R10Update.Step = 4;
                    else
                      BU98R10Update.Step = 1;
                  }
                  else
                  {
                    BU98R10Update.Cont = 0;
                    BU98R10Update.Addr++;
                    if (BU98R10Update.Addr >= BU98R10_DDRAM_SIZE)
                    {
                      BU98R10Update.Addr = 0;
                      BU98R10Update.En   = 0;
                    }
                  }
                  break;
                  
        case 1  : //请求写地址
                  BU98R10_0_Command_Write(BU98R10_CMD_ADSET);
                  BU98R10Update.Step = 2;
                  break;
                  
        case 2  : //写入地址
                  #if BU98R10_COLORFUL_LCD_MODE
                    BU98R10_0_Data_Write(BU98R10Update.Addr);
                  #else
                    BU98R10_0_Data_Write(BU98R10Update.Addr * 4);
                  #endif
                  BU98R10Update.Step = 3;
                  break;
        
        case 3  : //请求写数据
                  BU98R10_0_Command_Write(BU98R10_CMD_DATWR);
                  BU98R10Update.Step = 4;
                  break;
                  
        case 4  : //写入数据
                  BU98R10_0_Data_Write(BU98R10Chip1DDRAMBackup.Byte[BU98R10Update.Addr]);
                  BU98R10Update.Step = 5;
                  break;
                  
        case 5  : //地址调整
                  BU98R10Update.Addr++;
                  if (BU98R10Update.Addr >= BU98R10_DDRAM_SIZE)
                  {
                    BU98R10Update.Addr = 0;                    
                    BU98R10Update.Cont = 0;
                    BU98R10Update.En   = 0;
                  }
                  else                
                    BU98R10Update.Cont = 1;
                  
                  BU98R10Update.Step = 0;
                  break;
                  
        default : BU98R10Update.En   = 0;
                  BU98R10Update.Step = 0;
                  BU98R10Update.Cont = 0;
                  BU98R10Update.Addr = 0;
                  break;
      }
    }
    #endif
    
    #if ((USE_BU98R10_CHIP_0) || (USE_BU98R10_CHIP_1))
    else
    #endif
      BU98R10Update.En = 0;

  #endif
  }  
}

#if   USE_BU98R10_CHIP_0
/******************************************************************************
函数名：BU98R10_0_Command_Write
功  能：向BU98R10芯片0写控制命令
参  数：Cmd：要写入的命令
返回值：无
******************************************************************************/
void BU98R10_0_Command_Write(uint8_t Cmd)
{
   uint8_t i;

  //D/C = 0,表示发送命令
  BU98R10_0_SD(0);
  BU98R10_0_SCL(0);
  BU98R10_0_CSB(0);
  
   
  asm("nop");
  asm("nop");
  asm("nop");
  
  
  BU98R10_0_SCL (1);
  
  for (i = 0; i < 8; i++)
  {
    BU98R10_0_SCL (0);
    
    if (Cmd & 0x80)
      BU98R10_0_SD (1);
    else
      BU98R10_0_SD (0);
      
  asm("nop");
  asm("nop");
  asm("nop");
    
    BU98R10_0_SCL (1);
    
    Cmd <<= 1;
  }
  
  BU98R10_0_CSB (1);
  // uint8_t i;

  // //D/C = 0,表示发送命令
  // BU98R10_0_SD(0);
  // BU98R10_0_SCL(0);
  // BU98R10_0_CSB(0);
  
  // asm("nop");
  // asm("nop");
  // asm("nop");
  
  // BU98R10_0_SCL(1);
  
  // for (i = 0; i < 8; i++)
  // {
  //   BU98R10_0_SCL(0);
    
  //   if (Cmd & 0x80)
  //     BU98R10_0_SD(1);
  //   else
  //     BU98R10_0_SD(0);
      
  // asm("nop");
  // asm("nop");
  // asm("nop");
    
  //   BU98R10_0_SCL(1);
    
  //   Cmd <<= 1;
  // }
  
  // BU98R10_0_CSB(1);
}

/******************************************************************************
函数名：BU98R10_0_Data_Write
功  能：向BU98R10芯片0写数据
参  数：Dat：要写入的数据
返回值：无
******************************************************************************/
void BU98R10_0_Data_Write(uint8_t Dat)
{
  uint8_t i;

  //D/C = 1,表示发送数据
  BU98R10_0_SD  (1);
  BU98R10_0_SCL (0);
  BU98R10_0_CSB (0);
  
  asm("nop");
  asm("nop");
  asm("nop");
  
  BU98R10_0_SCL (1);
  
  for (i = 0; i < 8; i++)
  {
    BU98R10_0_SCL ( 0);
    
    if (Dat & 0x80)
      BU98R10_0_SD (1);
    else
      BU98R10_0_SD (0);
      
  asm("nop");
  asm("nop");
  asm("nop");
    
    BU98R10_0_SCL (1);
    
    Dat <<= 1;
  }
  
  BU98R10_0_CSB (1);

//   uint8_t i;

//    //D/C = 1,表示发送数据
//   BU98R10_0_SD(1);
//   BU98R10_0_SCL(0);
//   BU98R10_0_CSB(0);
  
// asm("nop");
//   asm("nop");
//   asm("nop");
  
//   BU98R10_0_SCL(1);
  
//   for (i = 0; i < 8; i++)
//   {
//     BU98R10_0_SCL(0);
    
//     if (Dat & 0x80)
//       BU98R10_0_SD(1);
//     else
//       BU98R10_0_SD(0);
      
//     asm("nop");
//     asm("nop");
//     asm("nop");
    
//     BU98R10_0_SCL(1);
    
//     Dat <<= 1;
//   }
  
//   BU98R10_0_CSB(1);
}
#endif

#if   USE_BU98R10_CHIP_1
/******************************************************************************
函数名：BU98R10_1_Command_Write
功  能：向BU98R10芯片1写控制命令
参  数：Cmd：要写入的命令
返回值：无
******************************************************************************/
void BU98R10_1_Command_Write(uint8_t Cmd)
{
  uint8_t i;

  //D/C = 0,表示发送命令
  BU98R10_1_SD(0);
  BU98R10_1_SCL(0);
  BU98R10_1_CSB(0);
  
  asm("nop");
  asm("nop");
  asm("nop");
  
  BU98R10_1_SCL(1);
  
  for (i = 0; i < 8; i++)
  {
    BU98R10_1_SCL(0);
    
    if (Cmd & 0x80)
      BU98R10_1_SD(1);
    else
      BU98R10_1_SD(0);
      
     asm("nop");
  asm("nop");
  asm("nop");
    
    BU98R10_1_SCL(1);
    
    Cmd <<= 1;
  }
  
  BU98R10_1_CSB(1);
}

/******************************************************************************
函数名：BU98R10_2_Data_Write
功  能：向BU98R10芯片2写数据
参  数：Dat：要写入的数据
返回值：无
******************************************************************************/
void BU98R10_2_Data_Write(uint8_t Dat)
{
  uint8_t i;

  //D/C = 1,表示发送数据
  BU98R10_2_SD(1);
  BU98R10_2_SCL(0);
  BU98R10_2_CSB(0);
  
  asm("nop");
  asm("nop");
  asm("nop");
  
  BU98R10_2_SCL(1);
  
  for (i = 0; i < 8; i++)
  {
    BU98R10_2_SCL(0);
    
    if (Dat & 0x80)
      BU98R10_2_SD(1);
    else
      BU98R10_2_SD(0);
      
  asm("nop");
  asm("nop");
  asm("nop");
    
    BU98R10_2_SCL(1);
    
    Dat <<= 1;
  }
  
  BU98R10_2_CSB(1);
}

#endif

#if   USE_BU98R10_CHIP_2
/******************************************************************************
函数名：BU98R10_2_Command_Write
功  能：向BU98R10芯片2写控制命令
参  数：Cmd：要写入的命令
返回值：无
******************************************************************************/
void BU98R10_2_Command_Write(uint8_t Cmd)
{
  uint8_t i;

  //D/C = 0,表示发送命令
  BU98R10_2_SD(0);
  BU98R10_2_SCL(0);
  BU98R10_2_CSB(0);
  
  asm("nop");
  asm("nop");
  asm("nop");
  
  BU98R10_2_SCL(1);
  
  for (i = 0; i < 8; i++)
  {
    BU98R10_2_SCL(0);
    
    if (Cmd & 0x80)
      BU98R10_2_SD(1);
    else
      BU98R10_2_SD(0);
      
     asm("nop");
  asm("nop");
  asm("nop");
    
    BU98R10_2_SCL(1);
    
    Cmd <<= 1;
  }
  
  BU98R10_2_CSB(1);
}

/******************************************************************************
函数名：BU98R10_1_Data_Write
功  能：向BU98R10芯片1写数据
参  数：Dat：要写入的数据
返回值：无
******************************************************************************/
void BU98R10_1_Data_Write(uint8_t Dat)
{
  uint8_t i;

  //D/C = 1,表示发送数据
  BU98R10_1_SD(1);
  BU98R10_1_SCL(0);
  BU98R10_1_CSB(0);
  
  asm("nop");
  asm("nop");
  asm("nop");
  
  BU98R10_1_SCL(1);
  
  for (i = 0; i < 8; i++)
  {
    BU98R10_1_SCL(0);
    
    if (Dat & 0x80)
      BU98R10_1_SD(1);
    else
      BU98R10_1_SD(0);
      
  asm("nop");
  asm("nop");
  asm("nop");
    
    BU98R10_1_SCL(1);
    
    Dat <<= 1;
  }
  
  BU98R10_1_CSB(1);
}

#endif

#if   BU98R10_WRITE_AT_SAME_TIME
/******************************************************************************
函数名：BU98R10_All_Command_Write
功  能：同时向BU98R10芯片0和芯片1写控制命令
参  数：Cmd：要写入的命令
返回值：无
******************************************************************************/
void BU98R10_All_Command_Write(uint8_t Cmd)
{
  uint8_t i;

  //D/C = 0,表示发送命令
  BU98R10_0_SD(0);
  BU98R10_1_SD(0);
  BU98R10_2_SD(0);
  
  BU98R10_0_SCL(0);
  BU98R10_1_SCL(0);
  BU98R10_2_SCL(0);
  
  BU98R10_0_CSB(0);
  BU98R10_1_CSB(0);
  BU98R10_2_CSB(0);
  
    
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");

  BU98R10_0_SCL(1);
  BU98R10_1_SCL(1);
  BU98R10_2_SCL(1);
  
      
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
  
  for (i = 0; i < 8; i++)
  {
    BU98R10_0_SCL(0);
    BU98R10_1_SCL(0);
    BU98R10_2_SCL(0);
    
    
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    
    if (Cmd & 0x80)
    {
      BU98R10_0_SD(1);
      BU98R10_1_SD(1);
      BU98R10_2_SD(1);
    }
    else
    {
      BU98R10_0_SD(0);
      BU98R10_1_SD(0);
      BU98R10_2_SD(0);
    }
      
    
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    
    BU98R10_0_SCL(1);
    BU98R10_1_SCL(1);
    BU98R10_2_SCL(1);
    
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    
    Cmd <<= 1;
  }
  
  BU98R10_0_CSB(1);
  BU98R10_1_CSB(1);
  BU98R10_2_CSB(1);
}

/******************************************************************************
函数名：BU98R10_All_Data_Write
功  能：同时向BU98R10芯片0和芯片1写数据
参  数：Dat0：要写入BU98R10芯片0的数据
        Dat1：要写入BU98R10芯片1的数据
返回值：无
******************************************************************************/
void BU98R10_All_Data_Write(uint8_t Dat0, uint8_t Dat1, uint8_t Dat2)
{
  uint8_t i;

  //D/C = 1,表示发送数据
  BU98R10_0_SD(1);
  BU98R10_1_SD(1);
  BU98R10_2_SD(1);
  
  BU98R10_0_SCL(0);
  BU98R10_1_SCL(0);
  BU98R10_2_SCL(0);
  
  BU98R10_0_CSB(0);
  BU98R10_1_CSB(0);
  BU98R10_2_CSB(0);
  
    
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
  
  BU98R10_0_SCL(1);
  BU98R10_1_SCL(1);
  BU98R10_2_SCL(1);
  
    
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");

  
  for (i = 0; i < 8; i++)
  {
    BU98R10_0_SCL(0);
    BU98R10_1_SCL(0);
    BU98R10_2_SCL(0);
    
    
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    
    if (Dat0 & 0x80)
      BU98R10_0_SD(1);
    else
      BU98R10_0_SD(0);
    
    if (Dat1 & 0x80)
      BU98R10_1_SD(1);
    else
      BU98R10_1_SD(0);
    
    if (Dat2 & 0x80)
      BU98R10_2_SD(1);
    else
      BU98R10_2_SD(0);
      
    
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    
    BU98R10_0_SCL(1);
    BU98R10_1_SCL(1);
    BU98R10_2_SCL(1);
    
    
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
    
    Dat0 <<= 1;
    Dat1 <<= 1;
    Dat2 <<= 1;
  }
  
  BU98R10_0_CSB(1);
  BU98R10_1_CSB(1);
  BU98R10_2_CSB(1);
}


void BU98R10_Clear_Data_Buffer(void)
{
  uint8_t i;

#if   USE_BU98R10_CHIP_0
  for(i=0;i<BU98R10_DDRAM_SIZE;i++)
  {
    BU98R10Chip0DDRAM.Byte[i] = 0x00;
    BU98R10Chip0DDRAMBackup.Byte[i] = 0x00;
  }
#endif

#if   USE_BU98R10_CHIP_1
  for(i=0;i<BU98R10_DDRAM_SIZE;i++)
  {
    BU98R10Chip1DDRAM.Byte[i] = 0x00;
    BU98R10Chip1DDRAMBackup.Byte[i] = 0x00;
  }
#endif

#if   USE_BU98R10_CHIP_2
  for(i=0;i<BU98R10_DDRAM_SIZE;i++)
  {
    BU98R10Chip2DDRAM.Byte[i] = 0x00;
    BU98R10Chip2DDRAMBackup.Byte[i] = 0x00;
  }
#endif
}


#endif
