#include <SPI.h>
#include <string.h>
#include <stdlib.h>		
#include "Ap_29demo.h"
#include "epd_2inch9.h"

/////////////////////delay//////////////////////////////////////
void driver_delay_us(unsigned int xus)  //1us
{
    for(;xus>1;xus--);
}
void driver_delay_xms(unsigned long xms) //1ms
{  
    unsigned long i = 0 , j=0;

    for(j=0;j<xms;j++)
    {
        for(i=0; i<256; i++);
    }
}
void DELAY_S(unsigned int delaytime)     
{
    int i,j,k;
    for(i=0;i<delaytime;i++)
    {
        for(j=0;j<4000;j++)           
        {
            for(k=0;k<222;k++);               
        }
    }
}
//////////////////////SPI///////////////////////////////////
void SPI_Delay(unsigned char xrate)
{
  unsigned char i;
  while(xrate)
  {
      for(i=0;i<2;i++);
      xrate--;
  }
}
void SPI_Write(unsigned char value)                                    
{                                                           
    unsigned char i;  
    SPI_Delay(1);
    for(i=0; i<8; i++)   
    {
        EPD_W21_CLK_0;
        SPI_Delay(1);
        if(value & 0x80)
           EPD_W21_MOSI_1;
        else
           EPD_W21_MOSI_0;   
        value = (value << 1); 
        SPI_Delay(1);
        driver_delay_us(1);
        EPD_W21_CLK_1; 
        SPI_Delay(1);
    }
}

void Epaper_Write_Command(unsigned char command)
{
   SPI_Delay(1);
   EPD_W21_CS_0;                   
   EPD_W21_DC_0;   // command write
   SPI_Write(command);
   EPD_W21_CS_1;
}
void Epaper_Write_Data(unsigned char data)
{
   SPI_Delay(1);
   EPD_W21_CS_0;                   
   EPD_W21_DC_1;   // command write
   SPI_Write(data);
   EPD_W21_CS_1;
}

/////////////////EPD settings Functions/////////////////////
void EPD_HW_Init(void)
{
  EPD_W21_RST_0;  // Module reset   
  delay(10);//At least 10ms delay 
  EPD_W21_RST_1;
  delay(10); //At least 10ms delay 
  
  Epaper_READBUSY();   
Epaper_Write_Command(0x4D);
  Epaper_Write_Data(0x78);

  Epaper_Write_Command(0x00); //PSR
  Epaper_Write_Data(0x0F);
  Epaper_Write_Data(0x29);

  Epaper_Write_Command(0x01); //PWRR
  Epaper_Write_Data(0x07);
  Epaper_Write_Data(0x00);
  
  Epaper_Write_Command(0x03); //POFS
  Epaper_Write_Data(0x10);
  Epaper_Write_Data(0x54);
  Epaper_Write_Data(0x44);
  
  Epaper_Write_Command(0x06); //BTST_P
  Epaper_Write_Data(0x05);
  Epaper_Write_Data(0x00);
  Epaper_Write_Data(0x3F);
  Epaper_Write_Data(0x0A);
  Epaper_Write_Data(0x25);
  Epaper_Write_Data(0x12);
  Epaper_Write_Data(0x1A); 

  Epaper_Write_Command(0x50); //CDI
  Epaper_Write_Data(0x37);
  
  Epaper_Write_Command(0x60); //TCON
  Epaper_Write_Data(0x02);
  Epaper_Write_Data(0x02);
  
  Epaper_Write_Command(0x61); //TRES
  Epaper_Write_Data(Source_BITS/256);   // Source_BITS_H
  Epaper_Write_Data(Source_BITS%256);   // Source_BITS_L
  Epaper_Write_Data(Gate_BITS/256);     // Gate_BITS_H
  Epaper_Write_Data(Gate_BITS%256);     // Gate_BITS_L  
  
  Epaper_Write_Command(0xE7);
  Epaper_Write_Data(0x1C);
  
  Epaper_Write_Command(0xE3); 
  Epaper_Write_Data(0x22);
  
  Epaper_Write_Command(0xB4);
  Epaper_Write_Data(0xD0);
  Epaper_Write_Command(0xB5);
  Epaper_Write_Data(0x03);
  
  Epaper_Write_Command(0xE9);
  Epaper_Write_Data(0x01); 

  Epaper_Write_Command(0x30);
  Epaper_Write_Data(0x08);  
  
  Epaper_Write_Command(0x04);
  Epaper_READBUSY();
  
}



////////////////////////////////////////Update/////////////////////////////////////////////
void EPD_Update(void)
{   
  Epaper_Write_Command(0x12); 
  Epaper_Write_Data(0x00);   
  Epaper_READBUSY();  

}

void EPD_DeepSleep(void)
{  
  Epaper_Write_Command(0x02); 
  Epaper_READBUSY();
  delay(100);

  Epaper_Write_Command(0x07); 
  Epaper_Write_Data(0xA5); 
}

void Epaper_READBUSY(void)
{ 
  while(1)
  {   //=1 BUSY
     if(isEPD_W21_BUSY==1) break;
  }  
}


void EPD_WhiteScreen_White(void)
{
  
  unsigned int i;
  //Write Data
  Epaper_Write_Command(0x10);      
  for(i=0;i<ALLSCREEN_BYTES;i++)       
  {
    Epaper_Write_Data(0X55);  
  }
  EPD_Update();
}

void EPD_WhiteScreen_Black(void)
{
  
  unsigned int i;
  //Write Data
  Epaper_Write_Command(0x10);      
  for(i=0;i<ALLSCREEN_BYTES;i++)       
  {
    Epaper_Write_Data(0X00);  
  }
  EPD_Update();
}


//Display all red
void EPD_WhiteScreen_Red(void)
{
  unsigned int i;
  //Write Data
  Epaper_Write_Command(0x10);      
  for(i=0;i<ALLSCREEN_BYTES;i++)       
  {
    Epaper_Write_Data(0Xff);  
  }
  EPD_Update();
}

//Display all yellow
void EPD_WhiteScreen_Yellow(void)
{
  unsigned int i;
  //Write Data
  Epaper_Write_Command(0x10);      
  for(i=0;i<ALLSCREEN_BYTES;i++)       
  {
    Epaper_Write_Data(0Xaa);  
  }
  EPD_Update();
}


unsigned char Color_get(unsigned char color)
{
  unsigned datas;
  switch(color)
  {
    case 0x00:
      datas=white;  
      break;    
    case 0x01:
      datas=yellow;
      break;
    case 0x02:
      datas=red;
      break;    
    case 0x03:
      datas=black;
      break;      
    default:
      break;      
  }
   return datas;
}

void PIC_display(const unsigned char* picData)
{
  unsigned int i,j;
  unsigned char temp1;
  unsigned char data_H1,data_H2,data_L1,data_L2,data;
   
  Epaper_Write_Command(0x10);        
  for(i=0;i<Gate_BITS;i++)  //Source_BITS*Gate_BITS/4
  { 
    for(j=0;j<Source_BITS/4;j++)
    {   
      temp1=pgm_read_byte(&picData[i*Source_BITS/4+j]); 

      data_H1=Color_get(temp1>>6&0x03)<<6;      
      data_H2=Color_get(temp1>>4&0x03)<<4;
      data_L1=Color_get(temp1>>2&0x03)<<2;
      data_L2=Color_get(temp1&0x03);
      
      data=data_H1|data_H2|data_L1|data_L2;
      Epaper_Write_Data(data);
    }
  } 
   //Refresh
    EPD_Update();  
}


