#include <string.h>
#include <stdlib.h>
#include <stdio.h>	
#include "2in9_epd.h"
#include <fcntl.h>
#include <wiringPiSPI.h>
#include <wiringPi.h>
//define pin conection in BCM number
/****************************
* PIN_CS     8 
* PIN_RST    17 
* PIN_DC     25
* PIN_BUSY   24
***************************/

unsigned char tmp[2];

void EPD_GPIO_Init(void)
{
    printf("Init gpio for wiringpi\r\n");
    if(wiringPiSetup() < 0)//use wiringpi Pin number
    { 
        printf("wiringPi lib init failed! \r\n");
    }  
    pinMode(PIN_RST,OUTPUT);
    pinMode(PIN_DC,OUTPUT);
    pinMode(PIN_CS,OUTPUT);
    pinMode(PIN_BUSY,INPUT); 
    wiringPiSPISetup(0,8000000);
    
	
}

void delay_xms(unsigned int xms)
{
	unsigned int i;
	while(xms--)
	{
		i=12000;
		while(i--);
	}
}

void Epaper_READBUSY(void)
{ 
	while(1)
	{	 //=1 BUSY
		 if(digitalRead(PIN_BUSY)==HIGH) break;
	}  
}

void Epaper_Write_Command(unsigned char cmd)
{
	digitalWrite(PIN_CS, 1); 
	digitalWrite(PIN_CS, 0); 
	digitalWrite(PIN_DC, 0);   // D/C#   0:command  1:data
	wiringPiSPIDataRW(0,&cmd,1); 
	digitalWrite(PIN_CS, 1); 
}

void Epaper_Write_Data(unsigned char data)
{
	digitalWrite(PIN_CS, 1); 
	digitalWrite(PIN_CS, 0); 
	digitalWrite(PIN_DC, 1);   // D/C#   0:command  1:data
	wiringPiSPIDataRW(0,&data,1); 
	digitalWrite(PIN_CS, 1); 
}


	
/////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////

//SSD1681
void EPD_HW_Init(void)
{

   delay_xms(20);
	digitalWrite(PIN_RST, 0);  // Module reset   
	delay_xms(40);//At least 10ms delay 
	digitalWrite(PIN_RST, 1);
	delay_xms(50); //At least 10ms delay 
	printf("ok"); 
		
  
  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();  
	
}



void EPD_DeepSleep(void)
{  	
  Epaper_Write_Command(0x02); //enter deep sleep
  Epaper_READBUSY();          //waiting for the electronic paper IC to release the idle signal
  delay(100); 
  Epaper_Write_Command(0x07); //enter deep sleep
  Epaper_Write_Data(0xA5); //enter deep sleep
  
}

void EPD_refresh(void)
{   
  Epaper_Write_Command(0x12); //Display Update Control
  Epaper_Write_Data(0x00);
  Epaper_READBUSY();   
}




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

//Clear screen display
void EPD_WhiteScreen_White(void)
{
  unsigned int i;
  //Write Data
  Epaper_Write_Command(0x10);      
  for(i=0;i<EPD_ARRAY;i++)       
  {
    Epaper_Write_Data(0X55);  
  }
  EPD_refresh();
}
//Display all black
void EPD_WhiteScreen_Black(void)
{
  unsigned int i;
  //Write Data
  Epaper_Write_Command(0x10);      
  for(i=0;i<EPD_ARRAY;i++)       
  {
    Epaper_Write_Data(0X00);  
  }
  EPD_refresh();
}


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

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


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=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_refresh();  
}

void GUI_display(unsigned char* picData)
{
  unsigned int Width, Height,i,j; 
    Width = (EPD_WIDTH % 4 == 0)? (EPD_WIDTH / 4 ): (EPD_WIDTH / 4 + 1);
    Height = EPD_HEIGHT;
    
    Epaper_Write_Command(0x04);
    Epaper_READBUSY();

    Epaper_Write_Command(0x10);
    for ( j = 0; j < Height; j++) {
        for ( i = 0; i < Width; i++) {
            Epaper_Write_Data(picData[i + j * Width]);
        }
    }

    EPD_refresh();

}


/***********************************************************
						end file
***********************************************************/

