waveshare_epaper

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

EPD_2in9d.c (14707B)


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