waveshare_epaper

Waveshare e-paper display shenanigans
git clone git://bsandro.tech/waveshare_epaper
Log | Files | Refs | README

EPD_4in2.c (23117B)


      1 /*****************************************************************************
      2 * | File      	:   EPD_4in2.c
      3 * | Author      :   Waveshare team
      4 * | Function    :   4.2inch e-paper
      5 * | Info        :
      6 *----------------
      7 * |	This version:   V3.1
      8 * | Date        :   2019-11-14
      9 * | Info        :
     10 * -----------------------------------------------------------------------------
     11 * V3.1(2019-11-14):
     12 * 1.Add 4 grayscale drive and display program
     13 *	 Add EPD_4IN2_4Gray_lut_vcom[]
     14 *	 Add EPD_4IN2_4Gray_lut_ww[]
     15 *	 Add EPD_4IN2_4Gray_lut_bw[]
     16 *	 Add EPD_4IN2_4Gray_lut_wb
     17 *	 Add EPD_4IN2_4Gray_lut_bb
     18 *	 Add EPD_4IN2_Partial_SetLut()
     19 *	 Add EPD_4IN2_4Gray_lut()
     20 *	 Add EPD_4IN2_Init_4Gray()
     21 *	 Add EPD_4IN2_4GrayDisplay(....)
     22 * 2.Add partial refresh display
     23 * 	 Add EPD_4IN2_Partial_lut_vcom1[]
     24 * 	 Add EPD_4IN2_Partial_lut_ww1[]
     25 * 	 Add EPD_4IN2_Partial_lut_bw1[]
     26 * 	 Add EPD_4IN2_Partial_lut_wb1[]
     27 * 	 Add EPD_4IN2_Partial_lut_bb1[]
     28 * 	 Add EPD_4IN2_Partial_SetLut()
     29 * 	 Add EPD_4IN2_PartialDisplay(...)
     30 * 	 Poor display, no display function by default
     31 *
     32 * V3.0(2019-06-13):
     33 * 1.Change:
     34 *    lut_vcomDC[]  => EPD_4IN2_lut_vcomDC[]
     35 *    lut_ww[] => EPD_4IN2_lut_ww[]
     36 *    lut_bw[] => EPD_4IN2_lut_bw[]
     37 *    lut_wb[] => EPD_4IN2_lut_wb[]
     38 *    lut_bb[] => EPD_4IN2_lut_bb[]
     39 *    EPD_Reset() => EPD_4IN2_Reset()
     40 *    EPD_SendCommand() => EPD_4IN2_SendCommand()
     41 *    EPD_SendData() => EPD_4IN2_SendData()
     42 *    EPD_WaitUntilIdle() => EPD_4IN2_ReadBusy()
     43 *    EPD_SetFullReg() => EPD_4IN2_SetFullReg()
     44 *    EPD_SetPartReg() => EPD_4IN2_SetPartReg()
     45 *    EPD_TurnOnDisplay() => EPD_4IN2_TurnOnDisplay()
     46 *    EPD_Init() => EPD_4IN2_Init()
     47 *    EPD_Clear() => EPD_4IN2_Clear()
     48 *    EPD_Display() => EPD_4IN2_Display()
     49 *    EPD_Sleep() => EPD_4IN2_Sleep()
     50 * 2.remove commands define:
     51 *    #define PANEL_SETTING                               0x00
     52 *    #define POWER_SETTING                               0x01
     53 *    #define POWER_OFF                                   0x02
     54 *    #define POWER_OFF_SEQUENCE_SETTING                  0x03
     55 *    #define POWER_ON                                    0x04
     56 *    #define POWER_ON_MEASURE                            0x05
     57 *    #define BOOSTER_SOFT_START                          0x06
     58 *    #define DEEP_SLEEP                                  0x07
     59 *    #define DATA_START_TRANSMISSION_1                   0x10
     60 *    #define DATA_STOP                                   0x11
     61 *    #define DISPLAY_REFRESH                             0x12
     62 *    #define DATA_START_TRANSMISSION_2                   0x13
     63 *    #define VCOM_LUT                                    0x20
     64 *    #define W2W_LUT                                     0x21
     65 *    #define B2W_LUT                                     0x22
     66 *    #define W2B_LUT                                     0x23
     67 *    #define B2B_LUT                                     0x24
     68 *    #define PLL_CONTROL                                 0x30
     69 *    #define TEMPERATURE_SENSOR_CALIBRATION              0x40
     70 *    #define TEMPERATURE_SENSOR_SELECTION                0x41
     71 *    #define TEMPERATURE_SENSOR_WRITE                    0x42
     72 *    #define TEMPERATURE_SENSOR_READ                     0x43
     73 *    #define VCOM_AND_DATA_INTERVAL_SETTING              0x50
     74 *    #define LOW_POWER_DETECTION                         0x51
     75 *    #define TCON_SETTING                                0x60
     76 *    #define RESOLUTION_SETTING                          0x61
     77 *    #define GET_STATUS                                  0x71
     78 *    #define AUTO_MEASURE_VCOM                           0x80
     79 *    #define READ_VCOM_VALUE                             0x81
     80 *    #define VCM_DC_SETTING                              0x82
     81 *    #define PARTIAL_WINDOW                              0x90
     82 *    #define PARTIAL_IN                                  0x91
     83 *    #define PARTIAL_OUT                                 0x92
     84 *    #define PROGRAM_MODE                                0xA0
     85 *    #define ACTIVE_PROGRAM                              0xA1
     86 *    #define READ_OTP_DATA                               0xA2
     87 *    #define POWER_SAVING                                0xE3
     88 * V2.0(2018-10-30):
     89 * 1.Remove:ImageBuff[EPD_HEIGHT * EPD_WIDTH / 8]
     90 * 2.Change:EPD_Display(UBYTE *Image)
     91 *   Need to pass parameters: pointer to cached data
     92 #
     93 # Permission is hereby granted, free of charge, to any person obtaining a copy
     94 # of this software and associated documnetation files (the "Software"), to deal
     95 # in the Software without restriction, including without limitation the rights
     96 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     97 # copies of the Software, and to permit persons to  whom the Software is
     98 # furished to do so, subject to the following conditions:
     99 #
    100 # The above copyright notice and this permission notice shall be included in
    101 # all copies or substantial portions of the Software.
    102 #
    103 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    104 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    105 # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    106 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    107 # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    108 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    109 # THE SOFTWARE.
    110 #
    111 ******************************************************************************/
    112 #include "EPD_4in2.h"
    113 #include "Debug.h"
    114 
    115 static const unsigned char EPD_4IN2_lut_vcom0[] = {
    116     0x00, 0x17, 0x00, 0x00, 0x00, 0x02,
    117     0x00, 0x17, 0x17, 0x00, 0x00, 0x02,
    118     0x00, 0x0A, 0x01, 0x00, 0x00, 0x01,
    119     0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02,
    120     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    121     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    122     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    123 };
    124 static const unsigned char EPD_4IN2_lut_ww[] = {
    125     0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
    126     0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
    127     0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
    128     0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
    129     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    130     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    131     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    132 };
    133 static const unsigned char EPD_4IN2_lut_bw[] = {
    134     0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
    135     0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
    136     0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
    137     0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
    138     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    139     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    140     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    141 };
    142 static const unsigned char EPD_4IN2_lut_wb[] = {
    143     0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
    144     0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
    145     0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
    146     0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
    147     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    148     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    149     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    150 };
    151 static const unsigned char EPD_4IN2_lut_bb[] = {
    152     0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
    153     0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
    154     0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
    155     0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
    156     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    157     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    158     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    159 };
    160 
    161 /******************************partial screen update LUT*********************************/
    162 const unsigned char EPD_4IN2_Partial_lut_vcom1[] ={
    163 0x00	,0x19	,0x01	,0x00	,0x00	,0x01,
    164 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    165 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    166 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    167 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    168 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    169 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    170 0x00	,0x00,	};
    171 
    172 const unsigned char EPD_4IN2_Partial_lut_ww1[] ={
    173 0x00	,0x19	,0x01	,0x00	,0x00	,0x01,
    174 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    175 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    176 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    177 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    178 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    179 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,};
    180 
    181 const unsigned char EPD_4IN2_Partial_lut_bw1[] ={
    182 0x80	,0x19	,0x01	,0x00	,0x00	,0x01,	
    183 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    184 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    185 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    186 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    187 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    188 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	};
    189 
    190 const unsigned char EPD_4IN2_Partial_lut_wb1[] ={
    191 0x40	,0x19	,0x01	,0x00	,0x00	,0x01,	
    192 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    193 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    194 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    195 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    196 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    197 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	};
    198 
    199 const unsigned char EPD_4IN2_Partial_lut_bb1[] ={
    200 0x00	,0x19	,0x01	,0x00	,0x00	,0x01,	
    201 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    202 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    203 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    204 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    205 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	
    206 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,	};
    207 
    208 /******************************gray*********************************/
    209 //0~3 gray
    210 const unsigned char EPD_4IN2_4Gray_lut_vcom[] =
    211 {
    212 0x00	,0x0A	,0x00	,0x00	,0x00	,0x01,
    213 0x60	,0x14	,0x14	,0x00	,0x00	,0x01,
    214 0x00	,0x14	,0x00	,0x00	,0x00	,0x01,
    215 0x00	,0x13	,0x0A	,0x01	,0x00	,0x01,
    216 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    217 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    218 0x00	,0x00	,0x00	,0x00	,0x00	,0x00
    219 				
    220 };
    221 //R21
    222 const unsigned char EPD_4IN2_4Gray_lut_ww[] ={
    223 0x40	,0x0A	,0x00	,0x00	,0x00	,0x01,
    224 0x90	,0x14	,0x14	,0x00	,0x00	,0x01,
    225 0x10	,0x14	,0x0A	,0x00	,0x00	,0x01,
    226 0xA0	,0x13	,0x01	,0x00	,0x00	,0x01,
    227 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    228 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    229 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    230 };
    231 //R22H	r
    232 const unsigned char EPD_4IN2_4Gray_lut_bw[] ={
    233 0x40	,0x0A	,0x00	,0x00	,0x00	,0x01,
    234 0x90	,0x14	,0x14	,0x00	,0x00	,0x01,
    235 0x00	,0x14	,0x0A	,0x00	,0x00	,0x01,
    236 0x99	,0x0C	,0x01	,0x03	,0x04	,0x01,
    237 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    238 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    239 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    240 };
    241 //R23H	w
    242 const unsigned char EPD_4IN2_4Gray_lut_wb[] ={
    243 0x40	,0x0A	,0x00	,0x00	,0x00	,0x01,
    244 0x90	,0x14	,0x14	,0x00	,0x00	,0x01,
    245 0x00	,0x14	,0x0A	,0x00	,0x00	,0x01,
    246 0x99	,0x0B	,0x04	,0x04	,0x01	,0x01,
    247 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    248 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    249 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    250 };
    251 //R24H	b
    252 const unsigned char EPD_4IN2_4Gray_lut_bb[] ={
    253 0x80	,0x0A	,0x00	,0x00	,0x00	,0x01,
    254 0x90	,0x14	,0x14	,0x00	,0x00	,0x01,
    255 0x20	,0x14	,0x0A	,0x00	,0x00	,0x01,
    256 0x50	,0x13	,0x01	,0x00	,0x00	,0x01,
    257 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    258 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    259 0x00	,0x00	,0x00	,0x00	,0x00	,0x00,
    260 };
    261 
    262 
    263 /******************************************************************************
    264 function :	Software reset
    265 parameter:
    266 ******************************************************************************/
    267 static void EPD_4IN2_Reset(void)
    268 {
    269     DEV_Digital_Write(EPD_RST_PIN, 1);
    270     DEV_Delay_ms(200);
    271     DEV_Digital_Write(EPD_RST_PIN, 0);
    272     DEV_Delay_ms(200);
    273     DEV_Digital_Write(EPD_RST_PIN, 1);
    274     DEV_Delay_ms(200);
    275 }
    276 
    277 /******************************************************************************
    278 function :	send command
    279 parameter:
    280      Reg : Command register
    281 ******************************************************************************/
    282 static void EPD_4IN2_SendCommand(UBYTE Reg)
    283 {
    284     DEV_Digital_Write(EPD_DC_PIN, 0);
    285     DEV_Digital_Write(EPD_CS_PIN, 0);
    286     DEV_SPI_WriteByte(Reg);
    287     DEV_Digital_Write(EPD_CS_PIN, 1);
    288 }
    289 
    290 /******************************************************************************
    291 function :	send data
    292 parameter:
    293     Data : Write data
    294 ******************************************************************************/
    295 static void EPD_4IN2_SendData(UBYTE Data)
    296 {
    297     DEV_Digital_Write(EPD_DC_PIN, 1);
    298     DEV_Digital_Write(EPD_CS_PIN, 0);
    299     DEV_SPI_WriteByte(Data);
    300     DEV_Digital_Write(EPD_CS_PIN, 1);
    301 }
    302 
    303 /******************************************************************************
    304 function :	Wait until the busy_pin goes LOW
    305 parameter:
    306 ******************************************************************************/
    307 void EPD_4IN2_ReadBusy(void)
    308 {
    309     Debug("e-Paper busy\r\n");
    310 	EPD_4IN2_SendCommand(0x71);
    311     while(DEV_Digital_Read(EPD_BUSY_PIN) == 0) {      //LOW: idle, HIGH: busy
    312 		EPD_4IN2_SendCommand(0x71);
    313         DEV_Delay_ms(100);
    314     }
    315     Debug("e-Paper busy release\r\n");
    316 }
    317 
    318 /******************************************************************************
    319 function :	Turn On Display
    320 parameter:
    321 ******************************************************************************/
    322 static void EPD_4IN2_TurnOnDisplay(void)
    323 {
    324     EPD_4IN2_SendCommand(0x12);
    325     DEV_Delay_ms(100);
    326     EPD_4IN2_ReadBusy();
    327 }
    328 
    329 /******************************************************************************
    330 function :	set the look-up tables
    331 parameter:
    332 ******************************************************************************/
    333 static void EPD_4IN2_SetLut(void)
    334 {
    335     UWORD count;
    336     EPD_4IN2_SendCommand(0x20);         //g vcom
    337     for(count=0; count<44; count++) {
    338         EPD_4IN2_SendData(EPD_4IN2_lut_vcom0[count]);
    339     }
    340 
    341     EPD_4IN2_SendCommand(0x21);
    342     for(count=0; count<42; count++) {
    343         EPD_4IN2_SendData(EPD_4IN2_lut_ww[count]);
    344     }
    345 
    346     EPD_4IN2_SendCommand(0x22);
    347     for(count=0; count<42; count++) {
    348         EPD_4IN2_SendData(EPD_4IN2_lut_bw[count]);
    349     }
    350 
    351     EPD_4IN2_SendCommand(0x23);
    352     for(count=0; count<42; count++) {
    353         EPD_4IN2_SendData(EPD_4IN2_lut_wb[count]);
    354     }
    355 
    356     EPD_4IN2_SendCommand(0x24);
    357     for(count=0; count<42; count++) {
    358         EPD_4IN2_SendData(EPD_4IN2_lut_bb[count]);
    359     }
    360 }
    361 
    362 static void EPD_4IN2_Partial_SetLut(void)
    363 {
    364 	unsigned int count;
    365 	EPD_4IN2_SendCommand(0x20);
    366 	for(count=0;count<44;count++)	     
    367 		{EPD_4IN2_SendData(EPD_4IN2_Partial_lut_vcom1[count]);}
    368 
    369 	EPD_4IN2_SendCommand(0x21);
    370 	for(count=0;count<42;count++)	     
    371 		{EPD_4IN2_SendData(EPD_4IN2_Partial_lut_ww1[count]);}   
    372 	
    373 	EPD_4IN2_SendCommand(0x22);
    374 	for(count=0;count<42;count++)	     
    375 		{EPD_4IN2_SendData(EPD_4IN2_Partial_lut_bw1[count]);} 
    376 
    377 	EPD_4IN2_SendCommand(0x23);
    378 	for(count=0;count<42;count++)	     
    379 		{EPD_4IN2_SendData(EPD_4IN2_Partial_lut_wb1[count]);} 
    380 
    381 	EPD_4IN2_SendCommand(0x24);
    382 	for(count=0;count<42;count++)	     
    383 		{EPD_4IN2_SendData(EPD_4IN2_Partial_lut_bb1[count]);}   
    384 }
    385 
    386 //LUT download
    387 static void EPD_4IN2_4Gray_lut(void)
    388 {
    389 	unsigned int count;	 
    390 	{
    391 		EPD_4IN2_SendCommand(0x20);							//vcom
    392 		for(count=0;count<42;count++)
    393 			{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_vcom[count]);}
    394 		
    395 	EPD_4IN2_SendCommand(0x21);							//red not use
    396 	for(count=0;count<42;count++)
    397 		{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_ww[count]);}
    398 
    399 		EPD_4IN2_SendCommand(0x22);							//bw r
    400 		for(count=0;count<42;count++)
    401 			{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_bw[count]);}
    402 
    403 		EPD_4IN2_SendCommand(0x23);							//wb w
    404 		for(count=0;count<42;count++)
    405 			{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_wb[count]);}
    406 
    407 		EPD_4IN2_SendCommand(0x24);							//bb b
    408 		for(count=0;count<42;count++)
    409 			{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_bb[count]);}
    410 
    411 		EPD_4IN2_SendCommand(0x25);							//vcom
    412 		for(count=0;count<42;count++)
    413 			{EPD_4IN2_SendData(EPD_4IN2_4Gray_lut_ww[count]);}
    414 	}	         
    415 }
    416 /******************************************************************************
    417 function :	Initialize the e-Paper register
    418 parameter:
    419 ******************************************************************************/
    420 void EPD_4IN2_Init(void)
    421 {
    422     EPD_4IN2_Reset();
    423 
    424     EPD_4IN2_SendCommand(0x01); // POWER SETTING
    425     EPD_4IN2_SendData(0x03);
    426     EPD_4IN2_SendData(0x00);
    427     EPD_4IN2_SendData(0x2b);
    428     EPD_4IN2_SendData(0x2b);
    429 
    430     EPD_4IN2_SendCommand(0x06); // boost soft start
    431     EPD_4IN2_SendData(0x17);		//A
    432     EPD_4IN2_SendData(0x17);		//B
    433     EPD_4IN2_SendData(0x17);		//C
    434 
    435     EPD_4IN2_SendCommand(0x04); // POWER_ON
    436     EPD_4IN2_ReadBusy();
    437 
    438     EPD_4IN2_SendCommand(0x00); // panel setting
    439     EPD_4IN2_SendData(0xbf); // KW-BF   KWR-AF	BWROTP 0f	BWOTP 1f
    440     EPD_4IN2_SendData(0x0d);
    441 
    442     EPD_4IN2_SendCommand(0x30); // PLL setting
    443     EPD_4IN2_SendData(0x3C); // 3A 100HZ   29 150Hz 39 200HZ	31 171HZ
    444 
    445     EPD_4IN2_SendCommand(0x61); // resolution setting
    446     EPD_4IN2_SendData(0x01);
    447     EPD_4IN2_SendData(0x90); //128
    448     EPD_4IN2_SendData(0x01); //
    449     EPD_4IN2_SendData(0x2c);
    450 
    451     EPD_4IN2_SendCommand(0x82); // vcom_DC setting
    452     EPD_4IN2_SendData(0x28);
    453 
    454     EPD_4IN2_SendCommand(0X50); // VCOM AND DATA INTERVAL SETTING
    455     EPD_4IN2_SendData(0x97); // 97white border 77black border		VBDF 17|D7 VBDW 97 VBDB 57		VBDF F7 VBDW 77 VBDB 37  VBDR B7
    456 
    457     EPD_4IN2_SetLut();
    458 }
    459 
    460 void EPD_4IN2_Init_4Gray(void)
    461 {
    462 	EPD_4IN2_Reset();
    463 	EPD_4IN2_SendCommand(0x01);			//POWER SETTING
    464 	EPD_4IN2_SendData (0x03);
    465 	EPD_4IN2_SendData (0x00);       //VGH=20V,VGL=-20V
    466 	EPD_4IN2_SendData (0x2b);		//VDH=15V															 
    467 	EPD_4IN2_SendData (0x2b);		//VDL=-15V
    468 	EPD_4IN2_SendData (0x13);
    469 
    470 	EPD_4IN2_SendCommand(0x06);         //booster soft start
    471 	EPD_4IN2_SendData (0x17);		//A
    472 	EPD_4IN2_SendData (0x17);		//B
    473 	EPD_4IN2_SendData (0x17);		//C 
    474 
    475 	EPD_4IN2_SendCommand(0x04);
    476 	EPD_4IN2_ReadBusy();
    477 
    478 	EPD_4IN2_SendCommand(0x00);			//panel setting
    479 	EPD_4IN2_SendData(0x3f);		//KW-3f   KWR-2F	BWROTP 0f	BWOTP 1f
    480 
    481 	EPD_4IN2_SendCommand(0x30);			//PLL setting
    482 	EPD_4IN2_SendData (0x3c);      	//100hz 
    483 
    484 	EPD_4IN2_SendCommand(0x61);			//resolution setting
    485 	EPD_4IN2_SendData (0x01);		//400
    486 	EPD_4IN2_SendData (0x90);     	 
    487 	EPD_4IN2_SendData (0x01);		//300
    488 	EPD_4IN2_SendData (0x2c);
    489 
    490 	EPD_4IN2_SendCommand(0x82);			//vcom_DC setting
    491 	EPD_4IN2_SendData (0x12);
    492 
    493 	EPD_4IN2_SendCommand(0X50);			//VCOM AND DATA INTERVAL SETTING			
    494 	EPD_4IN2_SendData(0x97);
    495 }
    496 /******************************************************************************
    497 function :	Clear screen
    498 parameter:
    499 ******************************************************************************/
    500 void EPD_4IN2_Clear(void)
    501 {
    502     UWORD Width, Height;
    503     Width = (EPD_4IN2_WIDTH % 8 == 0)? (EPD_4IN2_WIDTH / 8 ): (EPD_4IN2_WIDTH / 8 + 1);
    504     Height = EPD_4IN2_HEIGHT;
    505 
    506     EPD_4IN2_SendCommand(0x10);
    507     for (UWORD j = 0; j < Height; j++) {
    508         for (UWORD i = 0; i < Width; i++) {
    509             EPD_4IN2_SendData(0xFF);
    510         }
    511     }
    512 
    513     EPD_4IN2_SendCommand(0x13);
    514     for (UWORD j = 0; j < Height; j++) {
    515         for (UWORD i = 0; i < Width; i++) {
    516             EPD_4IN2_SendData(0xFF);
    517         }
    518     }
    519 	EPD_4IN2_SendCommand(0x12);		 //DISPLAY REFRESH 		
    520 	DEV_Delay_ms(10);	
    521     EPD_4IN2_TurnOnDisplay();
    522 }
    523 
    524 /******************************************************************************
    525 function :	Sends the image buffer in RAM to e-Paper and displays
    526 parameter:
    527 ******************************************************************************/
    528 void EPD_4IN2_Display(UBYTE *Image)
    529 {
    530     UWORD Width, Height;
    531     Width = (EPD_4IN2_WIDTH % 8 == 0)? (EPD_4IN2_WIDTH / 8 ): (EPD_4IN2_WIDTH / 8 + 1);
    532     Height = EPD_4IN2_HEIGHT;
    533 
    534     EPD_4IN2_SendCommand(0x13);
    535     for (UWORD j = 0; j < Height; j++) {
    536         for (UWORD i = 0; i < Width; i++) {
    537             EPD_4IN2_SendData(Image[i + j * Width]);
    538         }
    539     }
    540 		
    541     EPD_4IN2_TurnOnDisplay();
    542 }
    543 
    544 void EPD_4IN2_PartialDisplay(UWORD X_start,UWORD Y_start,UWORD X_end,UWORD Y_end, UBYTE *Image)
    545 {
    546 	UWORD Width, Height;
    547     Width = (EPD_4IN2_WIDTH % 8 == 0)? (EPD_4IN2_WIDTH / 8 ): (EPD_4IN2_WIDTH / 8 + 1);
    548     Height = EPD_4IN2_HEIGHT;
    549 	
    550 	X_start = (X_start % 8 == 0)? (X_start): (X_start/8*8+8);
    551 	X_end = (X_end % 8 == 0)? (X_end): (X_end/8*8+8);
    552 	
    553 	EPD_4IN2_SendCommand(0X50);
    554 	EPD_4IN2_SendData(0xf7);
    555 	DEV_Delay_ms(100);
    556 	
    557 	EPD_4IN2_SendCommand(0x82);			//vcom_DC setting  	
    558 	EPD_4IN2_SendData (0x08);	
    559 	EPD_4IN2_SendCommand(0X50);
    560 	EPD_4IN2_SendData(0x47);		
    561 	EPD_4IN2_Partial_SetLut();
    562 	EPD_4IN2_SendCommand(0x91);		//This command makes the display enter partial mode
    563 	EPD_4IN2_SendCommand(0x90);		//resolution setting
    564 	EPD_4IN2_SendData ((X_start)/256);
    565 	EPD_4IN2_SendData ((X_start)%256);   //x-start    
    566 
    567 	EPD_4IN2_SendData ((X_end )/256);		
    568 	EPD_4IN2_SendData ((X_end )%256-1);  //x-end
    569 
    570 	EPD_4IN2_SendData (Y_start/256);
    571 	EPD_4IN2_SendData (Y_start%256);   //y-start    
    572 
    573 	EPD_4IN2_SendData (Y_end/256);		
    574 	EPD_4IN2_SendData (Y_end%256-1);  //y-end
    575 	EPD_4IN2_SendData (0x28);	
    576 
    577 	EPD_4IN2_SendCommand(0x10);	       //writes Old data to SRAM for programming
    578     for (UWORD j = 0; j < Y_end - Y_start; j++) {
    579         for (UWORD i = 0; i < (X_end - X_start)/8; i++) {
    580             EPD_4IN2_SendData(Image[(Y_start + j)*Width + X_start/8 + i]);
    581         }
    582     }
    583 	EPD_4IN2_SendCommand(0x13);				 //writes New data to SRAM.
    584     for (UWORD j = 0; j < Y_end - Y_start; j++) {
    585         for (UWORD i = 0; i < (X_end - X_start)/8; i++) {
    586             EPD_4IN2_SendData(~Image[(Y_start + j)*Width + X_start/8 + i]);
    587         }
    588     }
    589 
    590 	EPD_4IN2_SendCommand(0x12);		 //DISPLAY REFRESH 		             
    591 	DEV_Delay_ms(10);     //The delay here is necessary, 200uS at least!!!     
    592 	EPD_4IN2_TurnOnDisplay();
    593 }
    594 
    595 void EPD_4IN2_4GrayDisplay(const UBYTE *Image)
    596 {
    597     UDOUBLE i,j,k,m;
    598     UBYTE temp1,temp2,temp3;
    599 /****Color display description****
    600       white  gray1  gray2  black
    601 0x10|  01     01     00     00
    602 0x13|  01     00     01     00
    603 *********************************/
    604 	EPD_4IN2_SendCommand(0x10);	       
    605 	// EPD_4IN2_HEIGHT
    606 	// EPD_4IN2_WIDTH
    607 	for(m = 0; m<EPD_4IN2_HEIGHT;m++)
    608 		for(i=0;i<EPD_4IN2_WIDTH/8;i++)
    609 		{
    610 			temp3=0;
    611 			for(j=0;j<2;j++)	
    612 			{
    613 				
    614 				temp1 = Image[(m*(EPD_4IN2_WIDTH/8)+i)*2+j];
    615 				for(k=0;k<2;k++)	
    616 				{
    617 					temp2 = temp1&0xC0 ;
    618 					if(temp2 == 0xC0)
    619 						temp3 |= 0x01;//white
    620 					else if(temp2 == 0x00)
    621 						temp3 |= 0x00;  //black
    622 					else if(temp2 == 0x80) 
    623 						temp3 |= 0x01;  //gray1
    624 					else //0x40
    625 						temp3 |= 0x00; //gray2
    626 					temp3 <<= 1;	
    627 					
    628 					temp1 <<= 2;
    629 					temp2 = temp1&0xC0 ;
    630 					if(temp2 == 0xC0)  //white
    631 						temp3 |= 0x01;
    632 					else if(temp2 == 0x00) //black
    633 						temp3 |= 0x00;
    634 					else if(temp2 == 0x80)
    635 						temp3 |= 0x01; //gray1
    636 					else    //0x40
    637 							temp3 |= 0x00;	//gray2	
    638 					if(j!=1 || k!=1)				
    639 						temp3 <<= 1;
    640 					
    641 					temp1 <<= 2;
    642 				}
    643 				
    644 			 }
    645 			EPD_4IN2_SendData(temp3);			
    646 		}
    647     // new  data
    648     EPD_4IN2_SendCommand(0x13);	 
    649 	for(m = 0; m<EPD_4IN2_HEIGHT;m++)
    650 		for(i=0;i<EPD_4IN2_WIDTH/8;i++)
    651 		{
    652 			temp3=0;
    653 			for(j=0;j<2;j++)	
    654 			{
    655 				temp1 = Image[(m*(EPD_4IN2_WIDTH/8)+i)*2+j];
    656 				for(k=0;k<2;k++)	
    657 				{
    658 					temp2 = temp1&0xC0 ;
    659 					if(temp2 == 0xC0)
    660 						temp3 |= 0x01;//white
    661 					else if(temp2 == 0x00)
    662 						temp3 |= 0x00;  //black
    663 					else if(temp2 == 0x80) 
    664 						temp3 |= 0x00;  //gray1
    665 					else //0x40
    666 						temp3 |= 0x01; //gray2
    667 					temp3 <<= 1;	
    668 					
    669 					temp1 <<= 2;
    670 					temp2 = temp1&0xC0 ;
    671 					if(temp2 == 0xC0)  //white
    672 						temp3 |= 0x01;
    673 					else if(temp2 == 0x00) //black
    674 						temp3 |= 0x00;
    675 					else if(temp2 == 0x80)
    676 						temp3 |= 0x00; //gray1
    677 					else    //0x40
    678 							temp3 |= 0x01;	//gray2
    679 					if(j!=1 || k!=1)					
    680 						temp3 <<= 1;
    681 					
    682 					temp1 <<= 2;
    683 				}
    684 				
    685 			 }
    686 			EPD_4IN2_SendData(temp3);	
    687 		}
    688     
    689     EPD_4IN2_4Gray_lut();
    690     EPD_4IN2_TurnOnDisplay();
    691 }
    692 /******************************************************************************
    693 function :	Enter sleep mode
    694 parameter:
    695 ******************************************************************************/
    696 void EPD_4IN2_Sleep(void)
    697 {
    698     EPD_4IN2_SendCommand(0x02); // POWER_OFF
    699     EPD_4IN2_ReadBusy();
    700     EPD_4IN2_SendCommand(0x07); // DEEP_SLEEP
    701     EPD_4IN2_SendData(0XA5);
    702 }