
#define EPD_WIDTH   400
#define EPD_HEIGHT  300
#define EPD_W21_RST_0	GPIO_ResetBits(GPIOE, GPIO_Pin_14)
#define EPD_W21_RST_1	GPIO_SetBits(GPIOE, GPIO_Pin_14)
#define isEPD_W21_BUSY GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_13) 
static const unsigned char lut_vcom[];	//5S波形
static const unsigned char lut_ww[];
static const unsigned char lut_bw[];
static const unsigned char lut_wb[];
static const unsigned char lut_bb[];
static const unsigned char lut_R20_GC[];	//GC全刷波形
static const unsigned char lut_R21_GC[];
static const unsigned char lut_R22_GC[];
static const unsigned char lut_R23_GC[];
static const unsigned char lut_R24_GC[];
static const unsigned char lut_R20_DU[];	//DU局刷波形
static const unsigned char lut_R21_DU[];
static const unsigned char lut_R22_DU[];
static const unsigned char lut_R23_DU[];
static const unsigned char lut_R24_DU[];


static void lut_GC(void);//写全刷波形
static void lut_DU(void);//写局刷波形
void EPD_init(void);//写初始化
void PIC_display_GC(const unsigned char* picData);//全刷刷屏
void PIC_display_DU(const unsigned char* picData);//局刷刷屏
void PIC_display(unsigned char NUM);//测试黑白画面
void EPD_sleep(void);//进入睡眠
void EPD_refresh(void);//开始刷屏
void lcd_chkstatus(void);//判断屏幕是否空闲
void EPD_Reset(void);//硬件复位	

static u8 lut_flag = 0;	//调用波形标志位



/*********************************************************************************************
示例流程
复位 --> 初始化 --> 全刷图片 --> 刷图... --> 睡眠（10次DU刷图需要一次GC刷图,退出睡眠需要重新复位初始化）
图片数据大小为EPD_WIDTH*EPD_HEIGHT/8byte，即1bit表示1个像素点；
*********************************************************************************************/
int main(void)
{
	 
	GPIO_Configuration();
	EPD_Reset();                  //复位
	EPD_init(); 		      //初始化  初始化后第一张画面需要全刷GC刷屏
	PIC_display_GC(gImage_1);	//全刷显示图片1画面
	delay_ms(300);
	while(1)
	{	
		PIC_display_DU(gImage_1);     //DU局刷显示画面1										 
		DELAY_S(2);	
		PIC_display_DU(gImage_2);     //DU局刷显示画面2									 
		DELAY_S(2);	
		PIC_display_DU(gImage_3);     //DU局刷显示画面3										 
		DELAY_S(2);		 
		PIC_display_DU(gImage_1);     //DU局刷显示画面4								 
		DELAY_S(2);			  
		PIC_display_DU(gImage_2);     //DU局刷显示画面5									 
		DELAY_S(2);	
		PIC_display_DU(gImage_3);     //DU局刷显示画面6									 
		DELAY_S(2);			 		 
		PIC_display_DU(gImage_1);     //DU局刷显示画面7								 
		DELAY_S(2);				 
		PIC_display_DU(gImage_2);     //DU局刷显示画面8								 
		DELAY_S(2);	
		PIC_display_DU(gImage_3);     //DU局刷显示画面9										  
		DELAY_S(2);				 		 				 
		PIC_display_DU(gImage_1);     //DU局刷显示画面10		 
		DELAY_S(2);	
		PIC_display_GC(gImage_2);     //GC全刷显示画面1，建议每10次局刷后进行一次全刷			 
		DELAY_S(2);	

		EPD_sleep();	//进入睡眠模式
		delay_ms(300);
		//退出睡眠模式需要硬件复位
		EPD_Reset();                //复位
		//复位后需要重新初始化
		EPD_init(); 
		//初始化后第一张画面需要全刷GC刷屏
		PIC_display_GC(gImage_3);   //EPD_picture			 
		DELAY_S(2);	
	}
	
}

/*GPIO初始化*/
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE,ENABLE); 						 
//=============================================================================
//LED -> PE12   D/C-->PE15	RST -- PE14
//=============================================================================			 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_15 |GPIO_Pin_14;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
  GPIO_Init(GPIOE, &GPIO_InitStructure);
	
//SDA--->PD10  SCK-->PD9  CS-->PD8  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;		//Port configuration
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 			
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;		 		
  GPIO_Init(GPIOD, &GPIO_InitStructure);	  	
		 				     	
//BUSY--->PE13     KEY -- PE11
  GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_11|GPIO_Pin_13 ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;		//如果出现一直busy,可将busy引脚模式配置成浮空输入模式
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOE, &GPIO_InitStructure);				//Initialize GPIO	
	
}


/*复位*/
void EPD_Reset(void)
{	
	EPD_W21_RST_1;
	delay_ms(10);	//At least 10ms delay 
	EPD_W21_RST_0;		// Module reset
	delay_ms(100);//At least 10ms delay 
	EPD_W21_RST_1;
	delay_ms(100);	//At least 10ms delay 
}


/*初始化*/
void EPD_init(void)
{	
	lut_flag = 0；
	EPD_W21_WriteCMD(0x00);       
	EPD_W21_WriteDATA(0x3F);//bit 3:Gate scan direction  bit 2:Source shift direction;
					//可通过这两位改变电子纸扫描方向，从而实现图片旋转（其他bit不变）
	EPD_W21_WriteDATA(0xca); 

	EPD_W21_WriteCMD(0x01);     
		EPD_W21_WriteDATA(0x03);     
		EPD_W21_WriteDATA(0x10);     
		EPD_W21_WriteDATA(0x3f);     
		EPD_W21_WriteDATA(0x3f);     
		EPD_W21_WriteDATA(0x03);     


		EPD_W21_WriteCMD(0x06);      
		EPD_W21_WriteDATA(0xE7);      
		EPD_W21_WriteDATA(0xE7);     
		EPD_W21_WriteDATA(0x3D);    

		EPD_W21_WriteCMD(0X60);      // TCON SETTING  (TCON) 
		EPD_W21_WriteDATA(0x22);       

		EPD_W21_WriteCMD(0x82);      // vcom设定
		EPD_W21_WriteDATA(0x00);     

		EPD_W21_WriteCMD(0x30);      // 帧频设定
		EPD_W21_WriteDATA(0x09);     //   50HZ       

		EPD_W21_WriteCMD(0xE3);      // 
		EPD_W21_WriteDATA(0x88);     //          

		EPD_W21_WriteCMD(0x61);      // Resolution setting
		EPD_W21_WriteDATA(0x01);       
		EPD_W21_WriteDATA(0x90);     
		EPD_W21_WriteDATA(0x01);     
		EPD_W21_WriteDATA(0x2C);     

		EPD_W21_WriteCMD (0X50);      // 
		EPD_W21_WriteDATA(0xb7);     // Border	   
}

/*全刷波形刷图片*/
void PIC_display_GC(const unsigned char* picData)
{
	unsigned int i;
	if(!lut_flag)
	{
		lut_flag = 1;
		EPD_W21_WriteCMD(0x10);		
		for(i=0;i<EPD_WIDTH*EPD_HEIGHT/8;i++)      
		{
			EPD_W21_WriteDATA(0xff);  
		}	
	}
	else
	{
		EPD_W21_WriteCMD (0X50);      // 
		EPD_W21_WriteDATA(0xd7);     // Border
	}
			
	EPD_W21_WriteCMD(0x13);  //Start data transfer
   	for(i=0;i<EPD_WIDTH*EPD_HEIGHT/8;i++)      
   	{
  		EPD_W21_WriteDATA(*picData);  //Transfer the actual displayed data
   		picData++;
   	}
	lut_GC();                   
	EPD_refresh();
}


/*局刷波形刷图片*/
void PIC_display_DU(const unsigned char* picData)
{
	unsigned int i;
	
	EPD_W21_WriteCMD (0X50);      // 
	EPD_W21_WriteDATA(0xd7);
	
	EPD_W21_WriteCMD(0x13);	  //Transfer new data	
	for(i=0;i<EPD_WIDTH*EPD_HEIGHT/8;i++)      
	{
		EPD_W21_WriteDATA(*picData);  //Transfer the actual displayed data
		picData++;
	}
	lut_DU();     		 //Transfer wavefrom data	     	         
	EPD_refresh();		//DISPLAY REFRESH   
}

//显示黑白
void PIC_display(unsigned char NUM)
{
	
	unsigned int row, column;
  
	if(!lut_flag)
	{
		lut_flag = 1;
		EPD_W21_WriteCMD(0x10);		
		for(i=0;i<EPD_WIDTH*EPD_HEIGHT/8;i++)      
		{
			EPD_W21_WriteDATA(0xff);  
		}	
	}
	else
	{
		EPD_W21_WriteCMD (0X50);      // 
		EPD_W21_WriteDATA(0xd7);     // Border
	}
	EPD_W21_WriteCMD(0x13);		     //Transfer new data
	for(column=0; column<EPD_HEIGHT; column++)   
	{
		for(row=0; row<EPD_WIDTH/8; row++)  
		{
			/*1为白，0为黑*/
			switch (NUM)
			{
				case PIC_WHITE:
				EPD_W21_WriteDATA(0xFF);
				break;  

				case PIC_BLACK:
				EPD_W21_WriteDATA(0x00);
				break;  
			}
		}
	}	
	lut_GC();                   
	EPD_refresh();
}

/*等待电子纸执行完上一条指令*/
//忙碌期间不接受 其他指令
void lcd_chkstatus(void)
{
	while(isEPD_W21_BUSY==0); //=0 busy                    
}


/*开始执行刷屏*/
void EPD_refresh(void)
{
	EPD_W21_WriteCMD(0x17);			//DISPLAY REFRESH 		
	EPD_W21_WriteDATA(0xA5);  
	lcd_chkstatus();
}



/*进入睡眠模式*/
void EPD_sleep(void)
{
	EPD_W21_WriteCMD (0x07);  	//deep sleep
	EPD_W21_WriteDATA(0xA5);
}




//LUT download
static void lut_GC(void)
{
	u8 count;
		EPD_W21_WriteCMD(0x20);							//vcom
	for(count=0;count<42;count++)
		{EPD_W21_WriteDATA(lut_R20_GC[count]);}

	EPD_W21_WriteCMD(0x21);							//red not use
	for(count=0;count<42;count++)
		{EPD_W21_WriteDATA(lut_R21_GC[count]);}

	EPD_W21_WriteCMD(0x24);							//wb w
	for(count=0;count<42;count++)
		{EPD_W21_WriteDATA(lut_R24_GC[count]);}

						
	EPD_W21_WriteCMD(0x22);							//bb b
	for(count=0;count<42;count++)
		{EPD_W21_WriteDATA(lut_R22_GC[count]);}			

	EPD_W21_WriteCMD(0x23);							//bw r
	for(count=0;count<42;count++)
		{EPD_W21_WriteDATA(lut_R23_GC[count]);}
	
}

//LUT download
static void lut_DU(void)
{
	u8 count;	 	
	EPD_W21_WriteCMD(0x20);							//vcom
	for(count=0;count<42;count++)
		{EPD_W21_WriteDATA(lut_R20_DU[count]);}

	EPD_W21_WriteCMD(0x21);							//red not use
	for(count=0;count<42;count++)
		{EPD_W21_WriteDATA(lut_R21_DU[count]);}

	EPD_W21_WriteCMD(0x24);							//bb b
	for(count=0;count<42;count++)
		{EPD_W21_WriteDATA(lut_R24_DU[count]);}			

	EPD_W21_WriteCMD(0x22);							//bw r
	for(count=0;count<42;count++)
		{EPD_W21_WriteDATA(lut_R22_DU[count]);}

	EPD_W21_WriteCMD(0x23);							//wb w
	for(count=0;count<42;count++)
		{EPD_W21_WriteDATA(lut_R23_DU[count]);}
	
}	 


/*************************软件模拟SPI***********************************************************/

#define EPD_W21_MOSI_0	GPIO_ResetBits(GPIOD, GPIO_Pin_10)
#define EPD_W21_MOSI_1	GPIO_SetBits(GPIOD, GPIO_Pin_10)

#define EPD_W21_CLK_0	GPIO_ResetBits(GPIOD, GPIO_Pin_9)
#define EPD_W21_CLK_1	GPIO_SetBits(GPIOD, GPIO_Pin_9)

#define EPD_W21_CS_0	GPIO_ResetBits(GPIOD, GPIO_Pin_8)
#define EPD_W21_CS_1	GPIO_SetBits(GPIOD, GPIO_Pin_8)

#define EPD_W21_DC_0	GPIO_ResetBits(GPIOE, GPIO_Pin_15)
#define EPD_W21_DC_1	GPIO_SetBits(GPIOE, GPIO_Pin_15)

//SPI发送一字节函数
void SPI_Write(unsigned char value)                                    
{                                                           
	unsigned char i;
	
	for(i=0; i<8; i++)   
	{
		EPD_W21_CLK_0;
	
		if(value & 0x80)
			EPD_W21_MOSI_1;
		else
			EPD_W21_MOSI_0;		
		value = (value << 1);
		EPD_W21_CLK_1;
			
	}
}
/*SPI写命令函数*/
void EPD_W21_WriteCMD(unsigned char command)
{
	
  	EPD_W21_CS_0;                   
	EPD_W21_DC_0;		// command write
	SPI_Write(command);
	EPD_W21_CS_1;
	EPD_W21_DC_1;		//
}
/*SPI写数据函数*/
void EPD_W21_WriteDATA(unsigned char data)
{
	
	EPD_W21_MOSI_0;
  	EPD_W21_CS_0;                   
	EPD_W21_DC_1;		// data write
	SPI_Write(data);
	EPD_W21_CS_1;
	EPD_W21_DC_1;		//
	EPD_W21_MOSI_0;
}

/**********************************
读取示例：
	u8 data = 0;
	EPD_W21_WriteCMD(0x71);	//status bit read，发送目标寄存器地址
	data = EPD_read();	//接收回读数据
**********************************/
unsigned char EPD_read(void)
{
	unsigned char i;
	unsigned char DATA_BUF;   

	EPD_W21_CS_0; 
      delay_us(5);  
	SDA_IN();			//数据脚设置为输入，不同平台不同引脚配置不同，可封装函数或宏
	EPD_W21_DC_1;		// data read
      delay_us(5);
	EPD_W21_CLK_0;
	delay_us(5);
      for(i=0;i<8;i++ )
	{
		DATA_BUF=DATA_BUF<<1;
		DATA_BUF|=READ_SDA;	//READ_SDA：读取数据脚电平状态
		EPD_W21_CLK_1;
		delay_us(5);			 
		EPD_W21_CLK_0;	
        	delay_us(5);			 
      }					 
      delay_us(5);		 
	EPD_W21_CS_1;
	EPD_W21_DC_1;			
	SDA_OUT();		//读取结束，数据脚设置成输出			
      return DATA_BUF;				
}

/*************************波形数据**************************************************************///GC全刷

// 5S波形
static const unsigned char lut_vcom[] =
{
  0x01,0x19,0x19,0x19,0x19,0x01,0x01,
  0x01,0x19,0x19,0x19,0x01,0x01,0x01,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

static const unsigned char lut_ww[] ={
   0x01,0x59,0x99,0x59,0x99,0x01,0x01,
  0x01,0x59,0x99,0x19,0x01,0x01,0x01,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,

};

static const unsigned char lut_bw[] ={
  0x01,0x59,0x99,0x59,0x99,0x01,0x01,
  0x01,0x59,0x99,0x19,0x01,0x01,0x01,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

static const unsigned char lut_wb[] ={
	
  0x01,0x19,0x99,0x59,0x99,0x01,0x01,
  0x01,0x59,0x99,0x59,0x01,0x01,0x01,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

static const unsigned char lut_bb[] ={
 0x01,0x19,0x99,0x59,0x99,0x01,0x01,
  0x01,0x59,0x99,0x59,0x01,0x01,0x01,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};


//GC全刷
static const unsigned char lut_R20_GC[] = 
{
  0x01,0x0f,0x0f,0x0f,0x01,0x01,0x01,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};	
//ww
static const unsigned char lut_R21_GC[] = 
{
  0x01,0x4f,0x8f,0x0f,0x01,0x01,0x01,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
//KW
static const unsigned char lut_R22_GC[] = 
{
  0x01,0x0f,0x8f,0x0f,0x01,0x01,0x01,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
//WK
static const unsigned char lut_R23_GC[] = 
{
  0x01,0x4f,0x8f,0x4f,0x01,0x01,0x01,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
//KK
static const unsigned char lut_R24_GC[] = 
{
  0x01,0x0f,0x8f,0x4f,0x01,0x01,0x01,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

// DU 局刷
static const unsigned char lut_R20_DU[] = 
{
  0x01,0x14,0x02,0x00,0x00,0x01,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};  
//WW
static const unsigned char lut_R21_DU[] =   
{
  0x01,0x14,0x82,0x00,0x00,0x01,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};    
//KW
static const unsigned char lut_R22_DU[] = 
{
  0x01,0x94,0x82,0x00,0x00,0x01,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
//WK
static const unsigned char lut_R23_DU[] = 
{
  0x01,0x54,0x42,0x00,0x00,0x01,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
//KK
static const unsigned char lut_R24_DU[] = 
{
  0x01,0x14,0x02,0x00,0x00,0x01,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,

};
