waveshare_epaper

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

EPD_2in13d.c (15419B)


      1 /*****************************************************************************
      2 * | File      	:   EPD_2in13d.c
      3 * | Author      :   Waveshare team
      4 * | Function    :   2.13inch e-paper d
      5 * | Info        :
      6 *----------------
      7 * |	This version:   V3.0
      8 * | Date        :   2019-06-12
      9 * | Info        :
     10 * -----------------------------------------------------------------------------
     11 * V3.0(2019-06-12):
     12 * 1.Change:
     13 *    lut_vcomDC[]  => EPD_2IN13D_lut_vcomDC[]
     14 *    lut_ww[] => EPD_2IN13D_lut_ww[]
     15 *    lut_bw[] => EPD_2IN13D_lut_bw[]
     16 *    lut_wb[] => EPD_2IN13D_lut_wb[]
     17 *    lut_bb[] => EPD_2IN13D_lut_bb[]
     18 *    lut_vcom1[] => EPD_2IN13D_lut_vcom1[]
     19 *    lut_ww1[] => EPD_2IN13D_lut_ww1[]
     20 *    lut_bw1[] => EPD_2IN13D_lut_bw1[]
     21 *    lut_wb1[] => EPD_2IN13D_lut_wb1[]
     22 *    lut_bb1[] => EPD_2IN13D_lut_bb1[]
     23 *    EPD_Reset() => EPD_2IN13D_Reset()
     24 *    EPD_SendCommand() => EPD_2IN13D_SendCommand()
     25 *    EPD_SendData() => EPD_2IN13D_SendData()
     26 *    EPD_WaitUntilIdle() => EPD_2IN13D_ReadBusy()
     27 *    EPD_SetFullReg() => EPD_2IN13D_SetFullReg()
     28 *    EPD_SetPartReg() => EPD_2IN13D_SetPartReg()
     29 *    EPD_TurnOnDisplay() => EPD_2IN13D_TurnOnDisplay()
     30 *    EPD_Init() => EPD_2IN13D_Init()
     31 *    EPD_Clear() => EPD_2IN13D_Clear()
     32 *    EPD_Display() => EPD_2IN13D_Display()
     33 *    EPD_Sleep() => EPD_2IN13D_Sleep()
     34 * V2.0(2018-11-13):
     35 * 1.Remove:ImageBuff[EPD_2IN13D_HEIGHT * EPD_2IN13D_WIDTH / 8]
     36 * 2.Change:EPD_Display(UBYTE *Image)
     37 *   Need to pass parameters: pointer to cached data
     38 * 3.Change:
     39 *   EPD_RST -> EPD_RST_PIN
     40 *   EPD_DC -> EPD_DC_PIN
     41 *   EPD_CS -> EPD_CS_PIN
     42 *   EPD_BUSY -> EPD_BUSY_PIN
     43 #
     44 # Permission is hereby granted, free of charge, to any person obtaining a copy
     45 # of this software and associated documnetation files (the "Software"), to deal
     46 # in the Software without restriction, including without limitation the rights
     47 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     48 # copies of the Software, and to permit persons to  whom the Software is
     49 # furished to do so, subject to the following conditions:
     50 #
     51 # The above copyright notice and this permission notice shall be included in
     52 # all copies or substantial portions of the Software.
     53 #
     54 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     55 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     56 # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     57 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     58 # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     59 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     60 # THE SOFTWARE.
     61 #
     62 ******************************************************************************/
     63 #include "EPD_2in13d.h"
     64 #include "Debug.h"
     65 
     66 /**
     67  * full screen update LUT
     68 **/
     69 static const unsigned char EPD_2IN13D_lut_vcomDC[] = {
     70     0x00, 0x08, 0x00, 0x00, 0x00, 0x02,
     71     0x60, 0x28, 0x28, 0x00, 0x00, 0x01,
     72     0x00, 0x14, 0x00, 0x00, 0x00, 0x01,
     73     0x00, 0x12, 0x12, 0x00, 0x00, 0x01,
     74     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     75     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     76     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     77     0x00, 0x00,
     78 };
     79 static const unsigned char EPD_2IN13D_lut_ww[] = {
     80     0x40, 0x08, 0x00, 0x00, 0x00, 0x02,
     81     0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
     82     0x40, 0x14, 0x00, 0x00, 0x00, 0x01,
     83     0xA0, 0x12, 0x12, 0x00, 0x00, 0x01,
     84     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     85     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     86     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     87 };
     88 static const unsigned char EPD_2IN13D_lut_bw[] = {
     89     0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
     90     0x90, 0x0F, 0x0F, 0x00, 0x00, 0x03,
     91     0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
     92     0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
     93     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     94     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     95     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     96 };
     97 static const unsigned char EPD_2IN13D_lut_wb[] = {
     98     0x80, 0x08, 0x00, 0x00, 0x00, 0x02,
     99     0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
    100     0x80, 0x14, 0x00, 0x00, 0x00, 0x01,
    101     0x50, 0x12, 0x12, 0x00, 0x00, 0x01,
    102     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    103     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    104     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    105 };
    106 static const unsigned char EPD_2IN13D_lut_bb[] = {
    107     0x80, 0x08, 0x00, 0x00, 0x00, 0x02,
    108     0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
    109     0x80, 0x14, 0x00, 0x00, 0x00, 0x01,
    110     0x50, 0x12, 0x12, 0x00, 0x00, 0x01,
    111     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    112     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    113     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    114 };
    115 
    116 
    117 /**
    118  * partial screen update LUT
    119 **/
    120 static const unsigned char EPD_2IN13D_lut_vcom1[] = {
    121     0x00, 0x19, 0x01, 0x00, 0x00, 0x01,
    122     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    123     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    124     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    125     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    126     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    127     0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    128     ,0x00, 0x00,
    129 };
    130 static const unsigned char EPD_2IN13D_lut_ww1[] = {
    131     0x00, 0x19, 0x01, 0x00, 0x00, 0x01,
    132     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    133     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    134     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    135     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    136     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    137     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    138 };
    139 static const unsigned char EPD_2IN13D_lut_bw1[] = {
    140     0x80, 0x19, 0x01, 0x00, 0x00, 0x01,
    141     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    142     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    143     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    144     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    145     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    146     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    147 };
    148 static const unsigned char EPD_2IN13D_lut_wb1[] = {
    149     0x40, 0x19, 0x01, 0x00, 0x00, 0x01,
    150     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    151     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    152     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    153     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    154     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    155     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    156 };
    157 static const unsigned char EPD_2IN13D_lut_bb1[] = {
    158     0x00, 0x19, 0x01, 0x00, 0x00, 0x01,
    159     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    160     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    161     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    162     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    163     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    164     0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    165 };
    166 
    167 
    168 /******************************************************************************
    169 function :	Software reset
    170 parameter:
    171 ******************************************************************************/
    172 static void EPD_2IN13D_Reset(void)
    173 {
    174     DEV_Digital_Write(EPD_RST_PIN, 1);
    175     DEV_Delay_ms(200);
    176     DEV_Digital_Write(EPD_RST_PIN, 0);
    177     DEV_Delay_ms(200);
    178     DEV_Digital_Write(EPD_RST_PIN, 1);
    179     DEV_Delay_ms(200);
    180 }
    181 
    182 /******************************************************************************
    183 function :	send command
    184 parameter:
    185      Reg : Command register
    186 ******************************************************************************/
    187 static void EPD_2IN13D_SendCommand(UBYTE Reg)
    188 {
    189     DEV_Digital_Write(EPD_DC_PIN, 0);
    190     DEV_Digital_Write(EPD_CS_PIN, 0);
    191     DEV_SPI_WriteByte(Reg);
    192     DEV_Digital_Write(EPD_CS_PIN, 1);
    193 }
    194 
    195 /******************************************************************************
    196 function :	send data
    197 parameter:
    198     Data : Write data
    199 ******************************************************************************/
    200 static void EPD_2IN13D_SendData(UBYTE Data)
    201 {
    202     DEV_Digital_Write(EPD_DC_PIN, 1);
    203     DEV_Digital_Write(EPD_CS_PIN, 0);
    204     DEV_SPI_WriteByte(Data);
    205     DEV_Digital_Write(EPD_CS_PIN, 1);
    206 }
    207 
    208 /******************************************************************************
    209 function :	Wait until the busy_pin goes LOW
    210 parameter:
    211 ******************************************************************************/
    212 static void EPD_2IN13D_ReadBusy(void)
    213 {
    214     Debug("e-Paper busy\r\n");
    215     UBYTE busy;
    216     do {
    217         EPD_2IN13D_SendCommand(0x71);
    218         busy = DEV_Digital_Read(EPD_BUSY_PIN);
    219         busy =!(busy & 0x01);
    220     } while(busy);
    221     DEV_Delay_ms(200);
    222     Debug("e-Paper busy release\r\n");
    223 }
    224 
    225 /******************************************************************************
    226 function :	LUT download
    227 parameter:
    228 ******************************************************************************/
    229 static void EPD_2IN13D_SetFullReg(void)
    230 {
    231     EPD_2IN13D_SendCommand(0X50);			//VCOM AND DATA INTERVAL SETTING
    232     EPD_2IN13D_SendData(0xb7);		//WBmode:VBDF 17|D7 VBDW 97 VBDB 57		WBRmode:VBDF F7 VBDW 77 VBDB 37  VBDR B7
    233 
    234     unsigned int count;
    235     EPD_2IN13D_SendCommand(0x20);
    236     for(count=0; count<44; count++) {
    237         EPD_2IN13D_SendData(EPD_2IN13D_lut_vcomDC[count]);
    238     }
    239 
    240     EPD_2IN13D_SendCommand(0x21);
    241     for(count=0; count<42; count++) {
    242         EPD_2IN13D_SendData(EPD_2IN13D_lut_ww[count]);
    243     }
    244 
    245     EPD_2IN13D_SendCommand(0x22);
    246     for(count=0; count<42; count++) {
    247         EPD_2IN13D_SendData(EPD_2IN13D_lut_bw[count]);
    248     }
    249 
    250     EPD_2IN13D_SendCommand(0x23);
    251     for(count=0; count<42; count++) {
    252         EPD_2IN13D_SendData(EPD_2IN13D_lut_wb[count]);
    253     }
    254 
    255     EPD_2IN13D_SendCommand(0x24);
    256     for(count=0; count<42; count++) {
    257         EPD_2IN13D_SendData(EPD_2IN13D_lut_bb[count]);
    258     }
    259 }
    260 
    261 /******************************************************************************
    262 function :	LUT download
    263 parameter:
    264 ******************************************************************************/
    265 static void EPD_2IN13D_SetPartReg(void)
    266 {
    267     EPD_2IN13D_SendCommand(0x82);			//vcom_DC setting
    268     EPD_2IN13D_SendData(0x00);
    269     EPD_2IN13D_SendCommand(0X50);
    270     EPD_2IN13D_SendData(0xb7);
    271 	
    272     unsigned int count;
    273     EPD_2IN13D_SendCommand(0x20);
    274     for(count=0; count<44; count++) {
    275         EPD_2IN13D_SendData(EPD_2IN13D_lut_vcom1[count]);
    276     }
    277 
    278     EPD_2IN13D_SendCommand(0x21);
    279     for(count=0; count<42; count++) {
    280         EPD_2IN13D_SendData(EPD_2IN13D_lut_ww1[count]);
    281     }
    282 
    283     EPD_2IN13D_SendCommand(0x22);
    284     for(count=0; count<42; count++) {
    285         EPD_2IN13D_SendData(EPD_2IN13D_lut_bw1[count]);
    286     }
    287 
    288     EPD_2IN13D_SendCommand(0x23);
    289     for(count=0; count<42; count++) {
    290         EPD_2IN13D_SendData(EPD_2IN13D_lut_wb1[count]);
    291     }
    292 
    293     EPD_2IN13D_SendCommand(0x24);
    294     for(count=0; count<42; count++) {
    295         EPD_2IN13D_SendData(EPD_2IN13D_lut_bb1[count]);
    296     }
    297 }
    298 
    299 /******************************************************************************
    300 function :	Turn On Display
    301 parameter:
    302 ******************************************************************************/
    303 static void EPD_2IN13D_TurnOnDisplay(void)
    304 {
    305     EPD_2IN13D_SendCommand(0x12);		 //DISPLAY REFRESH
    306     DEV_Delay_ms(10);     //!!!The delay here is necessary, 200uS at least!!!
    307 
    308     EPD_2IN13D_ReadBusy();
    309 }
    310 
    311 /******************************************************************************
    312 function :	Initialize the e-Paper register
    313 parameter:
    314 ******************************************************************************/
    315 void EPD_2IN13D_Init()
    316 {
    317     EPD_2IN13D_Reset();
    318 
    319     EPD_2IN13D_SendCommand(0x01);	//POWER SETTING
    320     EPD_2IN13D_SendData(0x03);
    321     EPD_2IN13D_SendData(0x00);
    322     EPD_2IN13D_SendData(0x2b);
    323     EPD_2IN13D_SendData(0x2b);
    324     EPD_2IN13D_SendData(0x03);
    325 
    326     EPD_2IN13D_SendCommand(0x06);	//boost soft start
    327     EPD_2IN13D_SendData(0x17);     //A
    328     EPD_2IN13D_SendData(0x17);     //B
    329     EPD_2IN13D_SendData(0x17);     //C
    330 
    331     EPD_2IN13D_SendCommand(0x04);
    332     EPD_2IN13D_ReadBusy();
    333 
    334     EPD_2IN13D_SendCommand(0x00);	//panel setting
    335     EPD_2IN13D_SendData(0xbf);     //LUT from OTP,128x296
    336     EPD_2IN13D_SendData(0x0e);     //VCOM to 0V fast
    337 
    338     EPD_2IN13D_SendCommand(0x30);	//PLL setting
    339     EPD_2IN13D_SendData(0x3a);     // 3a 100HZ   29 150Hz 39 200HZ	31 171HZ
    340 
    341     EPD_2IN13D_SendCommand(0x61);	//resolution setting
    342     EPD_2IN13D_SendData(EPD_2IN13D_WIDTH);
    343     EPD_2IN13D_SendData((EPD_2IN13D_HEIGHT >> 8) & 0xff);
    344     EPD_2IN13D_SendData(EPD_2IN13D_HEIGHT& 0xff);
    345 
    346     EPD_2IN13D_SendCommand(0x82);	//vcom_DC setting
    347     EPD_2IN13D_SendData(0x28);
    348 }
    349 
    350 /******************************************************************************
    351 function :	Clear screen
    352 parameter:
    353 ******************************************************************************/
    354 void EPD_2IN13D_Clear(void)
    355 {
    356     UWORD Width, Height;
    357     Width = (EPD_2IN13D_WIDTH % 8 == 0)? (EPD_2IN13D_WIDTH / 8 ): (EPD_2IN13D_WIDTH / 8 + 1);
    358     Height = EPD_2IN13D_HEIGHT;
    359 
    360     EPD_2IN13D_SendCommand(0x10);
    361     for (UWORD j = 0; j < Height; j++) {
    362         for (UWORD i = 0; i < Width; i++) {
    363             EPD_2IN13D_SendData(0x00);
    364         }
    365     }
    366 
    367     EPD_2IN13D_SendCommand(0x13);
    368     for (UWORD j = 0; j < Height; j++) {
    369         for (UWORD i = 0; i < Width; i++) {
    370             EPD_2IN13D_SendData(0xFF);
    371         }
    372     }
    373 
    374     EPD_2IN13D_SetFullReg();
    375     EPD_2IN13D_TurnOnDisplay();
    376 }
    377 
    378 /******************************************************************************
    379 function :	Sends the image buffer in RAM to e-Paper and displays
    380 parameter:
    381 ******************************************************************************/
    382 void EPD_2IN13D_Display(UBYTE *Image)
    383 {
    384     UWORD Width, Height;
    385     Width = (EPD_2IN13D_WIDTH % 8 == 0)? (EPD_2IN13D_WIDTH / 8 ): (EPD_2IN13D_WIDTH / 8 + 1);
    386     Height = EPD_2IN13D_HEIGHT;
    387 
    388     EPD_2IN13D_SendCommand(0x10);
    389     for (UWORD j = 0; j < Height; j++) {
    390         for (UWORD i = 0; i < Width; i++) {
    391             EPD_2IN13D_SendData(0x00);
    392         }
    393     }
    394     // Dev_Delay_ms(10);
    395 
    396     EPD_2IN13D_SendCommand(0x13);
    397     for (UWORD j = 0; j < Height; j++) {
    398         for (UWORD i = 0; i < Width; i++) {
    399             EPD_2IN13D_SendData(Image[i + j * Width]);
    400         }
    401     }
    402     // Dev_Delay_ms(10);
    403 
    404 		EPD_2IN13D_SetFullReg();
    405     EPD_2IN13D_TurnOnDisplay();
    406 }
    407 
    408 /******************************************************************************
    409 function :	Sends the image buffer in RAM to e-Paper and displays
    410 parameter:
    411 ******************************************************************************/
    412 void EPD_2IN13D_DisplayPart(UBYTE *Image)
    413 {
    414     /* Set partial Windows */
    415     EPD_2IN13D_SetPartReg();
    416     EPD_2IN13D_SendCommand(0x91);		//This command makes the display enter partial mode
    417     EPD_2IN13D_SendCommand(0x90);		//resolution setting
    418     EPD_2IN13D_SendData(0);           //x-start
    419     EPD_2IN13D_SendData(EPD_2IN13D_WIDTH - 1);       //x-end
    420 
    421     EPD_2IN13D_SendData(0);
    422     EPD_2IN13D_SendData(0);     //y-start
    423     EPD_2IN13D_SendData(EPD_2IN13D_HEIGHT / 256);
    424     EPD_2IN13D_SendData(EPD_2IN13D_HEIGHT % 256 - 1);  //y-end
    425     EPD_2IN13D_SendData(0x28);
    426 
    427     UWORD Width;
    428     Width = (EPD_2IN13D_WIDTH % 8 == 0)? (EPD_2IN13D_WIDTH / 8 ): (EPD_2IN13D_WIDTH / 8 + 1);
    429     
    430     /* send data */
    431     EPD_2IN13D_SendCommand(0x10);
    432     for (UWORD j = 0; j < EPD_2IN13D_HEIGHT; j++) {
    433         for (UWORD i = 0; i < Width; i++) {
    434             EPD_2IN13D_SendData(~Image[i + j * Width]);
    435         }
    436     }
    437 
    438     EPD_2IN13D_SendCommand(0x13);
    439     for (UWORD j = 0; j < EPD_2IN13D_HEIGHT; j++) {
    440         for (UWORD i = 0; i < Width; i++) {
    441             EPD_2IN13D_SendData(Image[i + j * Width]);
    442         }
    443     }
    444 
    445     /* Set partial refresh */    
    446     EPD_2IN13D_TurnOnDisplay();
    447 }
    448 
    449 
    450 /******************************************************************************
    451 function :	Enter sleep mode
    452 parameter:
    453 ******************************************************************************/
    454 void EPD_2IN13D_Sleep(void)
    455 {
    456     EPD_2IN13D_SendCommand(0X50);
    457     EPD_2IN13D_SendData(0xf7);
    458     EPD_2IN13D_SendCommand(0X02);  	//power off
    459     EPD_2IN13D_SendCommand(0X07);  	//deep sleep
    460     EPD_2IN13D_SendData(0xA5);
    461 }