waveshare_epaper

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

EPD_1in54b.c (13611B)


      1 /*****************************************************************************
      2 * | File      	:   EPD_1in54b.c
      3 * | Author      :   Waveshare team
      4 * | Function    :   1.54inch e-paper b
      5 * | Info        :
      6 *----------------
      7 * |	This version:   V3.1
      8 * | Date        :   2019-06-12
      9 * | Info        :
     10 * -----------------------------------------------------------------------------
     11 * V3.1(2019-06-12):
     12 * 1.Change:
     13 *    lut_vcom0[] => EPD_1IN54_lut_vcom0[]
     14 *    lut_w[] => EPD_1IN54_lut_w[] 
     15 *    lut_b[] => EPD_1IN54B_lut_b[]
     16 *    lut_g1[] => EPD_1IN54B_lut_g1[]
     17 *    lut_g2[] => EPD_1IN54B_lut_g2[]
     18 *    lut_vcom1[] => EPD_1IN54B_lut_vcom1[]
     19 *    lut_red0[] => EPD_1IN54B_lut_red0[]
     20 *    lut_red1[] => EPD_1IN54B_lut_red1[]
     21 *    EPD_Reset() => EPD_1IN54B_Reset()
     22 *    EPD_SendCommand() => EPD_1IN54B_SendCommand()
     23 *    EPD_SendData() => EPD_1IN54B_SendData()
     24 *    EPD_WaitUntilIdle() => EPD_1IN54B_ReadBusy()
     25 *    EPD_SetLutBw() => EPD_1IN54B_SetLutBw()
     26 *    EPD_SetLutBw => EPD_1IN54B_SetLutBw()
     27 *    EPD_Init() => EPD_1IN54B_Init()
     28 *    EPD_Clear() => EPD_1IN54B_Clear()
     29 *    EPD_Display() => EPD_1IN54B_Display()
     30 *    EPD_Sleep() => EPD_1IN54B_Sleep()
     31 * -----------------------------------------------------------------------------
     32 * V3.0(2019-04-24):
     33 * 1.remove commands define:
     34 *   #define PANEL_SETTING                               0x00
     35 *   #define POWER_SETTING                               0x01
     36 *   #define POWER_OFF                                   0x02
     37 *   #define POWER_OFF_SEQUENCE_SETTING                  0x03
     38 *   #define POWER_ON                                    0x04
     39 *   #define POWER_ON_MEASURE                            0x05
     40 *   #define BOOSTER_SOFT_START                          0x06
     41 *   #define DEEP_SLEEP                                  0x07
     42 *   #define DATA_START_TRANSMISSION_1                   0x10
     43 *   #define DATA_STOP                                   0x11
     44 *   #define DISPLAY_REFRESH                             0x12
     45 *   #define DATA_START_TRANSMISSION_2                   0x13
     46 *   #define PLL_CONTROL                                 0x30
     47 *   #define TEMPERATURE_SENSOR_COMMAND                  0x40
     48 *   #define TEMPERATURE_SENSOR_CALIBRATION              0x41
     49 *   #define TEMPERATURE_SENSOR_WRITE                    0x42
     50 *   #define TEMPERATURE_SENSOR_READ                     0x43
     51 *   #define VCOM_AND_DATA_INTERVAL_SETTING              0x50
     52 *   #define LOW_POWER_DETECTION                         0x51
     53 *   #define TCON_SETTING                                0x60
     54 *   #define TCON_RESOLUTION                             0x61
     55 *   #define SOURCE_AND_GATE_START_SETTING               0x62
     56 *   #define GET_STATUS                                  0x71
     57 *   #define AUTO_MEASURE_VCOM                           0x80
     58 *   #define VCOM_VALUE                                  0x81
     59 *   #define VCM_DC_SETTING_REGISTER                     0x82
     60 *   #define PROGRAM_MODE                                0xA0
     61 *   #define ACTIVE_PROGRAM                              0xA1
     62 *   #define READ_OTP_DATA                               0xA2
     63 *
     64 * -----------------------------------------------------------------------------
     65 * V2.0(2018-10-30):
     66 * 1.Remove:ImageBuff[EPD_1IN54B_HEIGHT * EPD_1IN54B_WIDTH / 8]
     67 * 2.Change:EPD_Display(UBYTE *Image)
     68 *   Need to pass parameters: pointer to cached data
     69 * 3.Change:
     70 *   EPD_RST -> EPD_RST_PIN
     71 *   EPD_DC -> EPD_DC_PIN
     72 *   EPD_CS -> EPD_CS_PIN
     73 *   EPD_BUSY -> EPD_BUSY_PIN
     74 #
     75 # Permission is hereby granted, free of charge, to any person obtaining a copy
     76 # of this software and associated documnetation files (the "Software"), to deal
     77 # in the Software without restriction, including without limitation the rights
     78 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     79 # copies of the Software, and to permit persons to  whom the Software is
     80 # furished to do so, subject to the following conditions:
     81 #
     82 # The above copyright notice and this permission notice shall be included in
     83 # all copies or substantial portions of the Software.
     84 #
     85 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     86 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     87 # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     88 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     89 # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     90 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     91 # THE SOFTWARE.
     92 #
     93 ******************************************************************************/
     94 #include "EPD_1in54b.h"
     95 #include "Debug.h"
     96 
     97 const unsigned char EPD_1IN54B_lut_vcom0[] = {0x0E, 0x14, 0x01, 0x0A, 0x06, 0x04, 0x0A, 0x0A, 0x0F, 0x03, 0x03, 0x0C, 0x06, 0x0A, 0x00};
     98 const unsigned char EPD_1IN54B_lut_w[] = {0x0E, 0x14, 0x01, 0x0A, 0x46, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x86, 0x0A, 0x04};
     99 const unsigned char EPD_1IN54B_lut_b[] = {0x0E, 0x14, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x06, 0x4A, 0x04};
    100 const unsigned char EPD_1IN54B_lut_g1[] = {0x8E, 0x94, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x06, 0x0A, 0x04};
    101 const unsigned char EPD_1IN54B_lut_g2[] = {0x8E, 0x94, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x06, 0x0A, 0x04};
    102 const unsigned char EPD_1IN54B_lut_vcom1[] = {0x03, 0x1D, 0x01, 0x01, 0x08, 0x23, 0x37, 0x37, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    103 const unsigned char EPD_1IN54B_lut_red0[] = {0x83, 0x5D, 0x01, 0x81, 0x48, 0x23, 0x77, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    104 const unsigned char EPD_1IN54B_lut_red1[] = {0x03, 0x1D, 0x01, 0x01, 0x08, 0x23, 0x37, 0x37, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    105 
    106 /******************************************************************************
    107 function :	Software reset
    108 parameter:
    109 ******************************************************************************/
    110 static void EPD_1IN54B_Reset(void)
    111 {
    112     DEV_Digital_Write(EPD_RST_PIN, 1);
    113     DEV_Delay_ms(100);
    114     DEV_Digital_Write(EPD_RST_PIN, 0);
    115     DEV_Delay_ms(10);
    116     DEV_Digital_Write(EPD_RST_PIN, 1);
    117     DEV_Delay_ms(100);
    118 }
    119 
    120 /******************************************************************************
    121 function :	send command
    122 parameter:
    123      Reg : Command register
    124 ******************************************************************************/
    125 static void EPD_1IN54B_SendCommand(UBYTE Reg)
    126 {
    127     DEV_Digital_Write(EPD_DC_PIN, 0);
    128     DEV_Digital_Write(EPD_CS_PIN, 0);
    129     DEV_SPI_WriteByte(Reg);
    130     DEV_Digital_Write(EPD_CS_PIN, 1);
    131 }
    132 
    133 /******************************************************************************
    134 function :	send data
    135 parameter:
    136     Data : Write data
    137 ******************************************************************************/
    138 static void EPD_1IN54B_SendData(UBYTE Data)
    139 {
    140     DEV_Digital_Write(EPD_DC_PIN, 1);
    141     DEV_Digital_Write(EPD_CS_PIN, 0);
    142     DEV_SPI_WriteByte(Data);
    143     DEV_Digital_Write(EPD_CS_PIN, 1);
    144 }
    145 
    146 /******************************************************************************
    147 function :	Wait until the busy_pin goes LOW
    148 parameter:
    149 ******************************************************************************/
    150 static void EPD_1IN54B_ReadBusy(void)
    151 {
    152     Debug("e-Paper busy\r\n");
    153     while(1) {
    154         if(DEV_Digital_Read(EPD_BUSY_PIN) == 1)
    155             break;
    156     }
    157     DEV_Delay_ms(200);
    158     Debug("e-Paper busy release\r\n");
    159 }
    160 
    161 /******************************************************************************
    162 function :	Set the look-up black and white tables
    163 parameter:
    164 ******************************************************************************/
    165 static void EPD_1IN54B_SetLutBw(void)
    166 {
    167     UWORD count;
    168     EPD_1IN54B_SendCommand(0x20);// g vcom
    169     for(count = 0; count < 15; count++) {
    170         EPD_1IN54B_SendData(EPD_1IN54B_lut_vcom0[count]);
    171     }
    172     EPD_1IN54B_SendCommand(0x21);// g ww --
    173     for(count = 0; count < 15; count++) {
    174         EPD_1IN54B_SendData(EPD_1IN54B_lut_w[count]);
    175     }
    176     EPD_1IN54B_SendCommand(0x22);// g bw r
    177     for(count = 0; count < 15; count++) {
    178         EPD_1IN54B_SendData(EPD_1IN54B_lut_b[count]);
    179     }
    180     EPD_1IN54B_SendCommand(0x23);// g wb w
    181     for(count = 0; count < 15; count++) {
    182         EPD_1IN54B_SendData(EPD_1IN54B_lut_g1[count]);
    183     }
    184     EPD_1IN54B_SendCommand(0x24);// g bb b
    185     for(count = 0; count < 15; count++) {
    186         EPD_1IN54B_SendData(EPD_1IN54B_lut_g2[count]);
    187     }
    188 }
    189 
    190 /******************************************************************************
    191 function :	Set the look-up red tables
    192 parameter:
    193 ******************************************************************************/
    194 static void EPD_1IN54B_SetLutRed(void)
    195 {
    196     UWORD count;
    197     EPD_1IN54B_SendCommand(0x25);
    198     for(count = 0; count < 15; count++) {
    199         EPD_1IN54B_SendData(EPD_1IN54B_lut_vcom1[count]);
    200     }
    201     EPD_1IN54B_SendCommand(0x26);
    202     for(count = 0; count < 15; count++) {
    203         EPD_1IN54B_SendData(EPD_1IN54B_lut_red0[count]);
    204     }
    205     EPD_1IN54B_SendCommand(0x27);
    206     for(count = 0; count < 15; count++) {
    207         EPD_1IN54B_SendData(EPD_1IN54B_lut_red1[count]);
    208     }
    209 }
    210 
    211 /******************************************************************************
    212 function :	Initialize the e-Paper register
    213 parameter:
    214 ******************************************************************************/
    215 void EPD_1IN54B_Init(void)
    216 {
    217     EPD_1IN54B_Reset();
    218 
    219     EPD_1IN54B_SendCommand(0x01);// POWER_SETTING
    220     EPD_1IN54B_SendData(0x07);
    221     EPD_1IN54B_SendData(0x00);
    222     EPD_1IN54B_SendData(0x08);
    223     EPD_1IN54B_SendData(0x00);
    224     EPD_1IN54B_SendCommand(0x06);// BOOSTER_SOFT_START
    225     EPD_1IN54B_SendData(0x07);
    226     EPD_1IN54B_SendData(0x07);
    227     EPD_1IN54B_SendData(0x07);
    228     EPD_1IN54B_SendCommand(0x04);// POWER_ON
    229 
    230     EPD_1IN54B_ReadBusy();
    231 
    232     EPD_1IN54B_SendCommand(0X00);// PANEL_SETTING
    233     EPD_1IN54B_SendData(0xcf);
    234     EPD_1IN54B_SendCommand(0X50);// VCOM_AND_DATA_INTERVAL_SETTING
    235     EPD_1IN54B_SendData(0x37);// 0xF0
    236     EPD_1IN54B_SendCommand(0x30);// PLL_CONTROL
    237     EPD_1IN54B_SendData(0x39);
    238     EPD_1IN54B_SendCommand(0x61);// TCON_RESOLUTION set x and y
    239     EPD_1IN54B_SendData(0xC8);// 200
    240     EPD_1IN54B_SendData(0x00);// y High eight: 0
    241     EPD_1IN54B_SendData(0xC8);// y Low eight: 200
    242     EPD_1IN54B_SendCommand(0x82);// VCM_DC_SETTING_REGISTER
    243     EPD_1IN54B_SendData(0x0E);
    244 
    245     EPD_1IN54B_SetLutBw();
    246     EPD_1IN54B_SetLutRed();
    247 }
    248 
    249 /******************************************************************************
    250 function :	Clear screen
    251 parameter:
    252 ******************************************************************************/
    253 void EPD_1IN54B_Clear(void)
    254 {
    255     UWORD Width, Height;
    256     Width = (EPD_1IN54B_WIDTH % 8 == 0)? (EPD_1IN54B_WIDTH / 8 ): (EPD_1IN54B_WIDTH / 8 + 1);
    257     Height = EPD_1IN54B_HEIGHT;
    258 
    259     //send black data
    260     EPD_1IN54B_SendCommand(0x10);// DATA_START_TRANSMISSION_1
    261     DEV_Delay_ms(2);
    262     for(UWORD i = 0; i < Height; i++) {
    263         for(UWORD i = 0; i < Width; i++) {
    264             EPD_1IN54B_SendData(0xFF);
    265             EPD_1IN54B_SendData(0xFF);
    266         }
    267     }
    268     DEV_Delay_ms(2);
    269 
    270     //send red data
    271     EPD_1IN54B_SendCommand(0x13);// DATA_START_TRANSMISSION_2
    272     DEV_Delay_ms(2);
    273     for(UWORD i = 0; i < Height; i++) {
    274         for(UWORD i = 0; i < Width; i++) {
    275             EPD_1IN54B_SendData(0xFF);
    276         }
    277     }
    278     DEV_Delay_ms(2);
    279 
    280     EPD_1IN54B_SendCommand(0x12);// DISPLAY_REFRESH
    281     EPD_1IN54B_ReadBusy();
    282 }
    283 
    284 /******************************************************************************
    285 function :	Sends the image buffer in RAM to e-Paper and displays
    286 parameter:
    287 ******************************************************************************/
    288 void EPD_1IN54B_Display(const UBYTE *blackimage, const UBYTE *redimage)
    289 {
    290     UBYTE Temp = 0x00;
    291     UWORD Width, Height;
    292     Width = (EPD_1IN54B_WIDTH % 8 == 0)? (EPD_1IN54B_WIDTH / 8 ): (EPD_1IN54B_WIDTH / 8 + 1);
    293     Height = EPD_1IN54B_HEIGHT;
    294 
    295     EPD_1IN54B_SendCommand(0x10);// DATA_START_TRANSMISSION_1
    296     for (UWORD j = 0; j < Height; j++) {
    297         for (UWORD i = 0; i < Width; i++) {
    298             Temp = 0x00;
    299             for (int bit = 0; bit < 4; bit++) {
    300                 if ((blackimage[i + j * Width] & (0x80 >> bit)) != 0) {
    301                     Temp |= 0xC0 >> (bit * 2);
    302                 }
    303             }
    304             EPD_1IN54B_SendData(Temp);
    305             Temp = 0x00;
    306             for (int bit = 4; bit < 8; bit++) {
    307                 if ((blackimage[i + j * Width] & (0x80 >> bit)) != 0) {
    308                     Temp |= 0xC0 >> ((bit - 4) * 2);
    309                 }
    310             }
    311             EPD_1IN54B_SendData(Temp);
    312         }
    313     }
    314     DEV_Delay_ms(2);
    315 
    316     EPD_1IN54B_SendCommand(0x13);// DATA_START_TRANSMISSION_2
    317     for (UWORD j = 0; j < Height; j++) {
    318         for (UWORD i = 0; i < Width; i++) {
    319             EPD_1IN54B_SendData(redimage[i + j * Width]);
    320         }
    321     }
    322     DEV_Delay_ms(2);
    323 
    324     //Display refresh
    325     EPD_1IN54B_SendCommand(0x12);// DISPLAY_REFRESH
    326     EPD_1IN54B_ReadBusy();
    327 }
    328 
    329 /******************************************************************************
    330 function :	Enter sleep mode
    331 parameter:
    332 ******************************************************************************/
    333 void EPD_1IN54B_Sleep(void)
    334 {
    335     EPD_1IN54B_SendCommand(0x50);// VCOM_AND_DATA_INTERVAL_SETTING
    336     EPD_1IN54B_SendData(0x17);
    337     EPD_1IN54B_SendCommand(0x82);// VCM_DC_SETTING_REGISTER
    338     EPD_1IN54B_SendData(0x00);
    339     EPD_1IN54B_SendCommand(0x01);// POWER_SETTING
    340     EPD_1IN54B_SendData(0x02);
    341     EPD_1IN54B_SendData(0x00);
    342     EPD_1IN54B_SendData(0x00);
    343     EPD_1IN54B_SendData(0x00);
    344     EPD_1IN54B_ReadBusy();
    345     DEV_Delay_ms(1000);
    346 	
    347     EPD_1IN54B_SendCommand(0x02);// POWER_OFF
    348 }