EPD_2in9.c (11222B)
1 /***************************************************************************** 2 * | File : EPD_2in9.c 3 * | Author : Waveshare team 4 * | Function : 2.9inch e-paper 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_full_update[] => EPD_2IN9_lut_full_update[] 14 * lut_partial_update[] => EPD_2IN9_lut_partial_update[] 15 * EPD_Reset() => EPD_2IN9_Reset() 16 * EPD_SendCommand() => EPD_2IN9_SendCommand() 17 * EPD_SendData() => EPD_2IN9_SendData() 18 * EPD_WaitUntilIdle() => EPD_2IN9_ReadBusy() 19 * EPD_SetLut() => EPD_2IN9_SetLut() 20 * EPD_SetWindow() => EPD_2IN9_SetWindow() 21 * EPD_SetCursor() => EPD_2IN9_SetCursor() 22 * EPD_TurnOnDisplay() => EPD_2IN9_TurnOnDisplay() 23 * EPD_Init() => EPD_2IN9_Init() 24 * EPD_Clear() => EPD_2IN9_Clear() 25 * EPD_Display() => EPD_2IN9_Display() 26 * EPD_Sleep() => EPD_2IN9_Sleep() 27 * 2.remove commands define: 28 * #define DRIVER_OUTPUT_CONTROL 0x01 29 * #define BOOSTER_SOFT_START_CONTROL 0x0C 30 * #define GATE_SCAN_START_POSITION 0x0F 31 * #define DEEP_SLEEP_MODE 0x10 32 * #define DATA_ENTRY_MODE_SETTING 0x11 33 * #define SW_RESET 0x12 34 * #define TEMPERATURE_SENSOR_CONTROL 0x1A 35 * #define MASTER_ACTIVATION 0x20 36 * #define DISPLAY_UPDATE_CONTROL_1 0x21 37 * #define DISPLAY_UPDATE_CONTROL_2 0x22 38 * #define WRITE_RAM 0x24 39 * #define WRITE_VCOM_REGISTER 0x2C 40 * #define WRITE_LUT_REGISTER 0x32 41 * #define SET_DUMMY_LINE_PERIOD 0x3A 42 * #define SET_GATE_TIME 0x3B 43 * #define BORDER_WAVEFORM_CONTROL 0x3C 44 * #define SET_RAM_X_ADDRESS_START_END_POSITION 0x44 45 * #define SET_RAM_Y_ADDRESS_START_END_POSITION 0x45 46 * #define SET_RAM_X_ADDRESS_COUNTER 0x4E 47 * #define SET_RAM_Y_ADDRESS_COUNTER 0x4F 48 * #define TERMINATE_FRAME_READ_WRITE 0xFF 49 * ----------------------------------------------------------------------------- 50 * V2.0(2018-11-06): 51 * 1.Remove:ImageBuff[EPD_2IN9_HEIGHT * EPD_2IN9_WIDTH / 8] 52 * 2.Change:EPD_Display(UBYTE *Image) 53 * Need to pass parameters: pointer to cached data 54 * 3.Change: 55 * EPD_RST -> EPD_RST_PIN 56 * EPD_DC -> EPD_DC_PIN 57 * EPD_CS -> EPD_CS_PIN 58 * EPD_BUSY -> EPD_BUSY_PIN 59 # 60 # Permission is hereby granted, free of charge, to any person obtaining a copy 61 # of this software and associated documnetation files (the "Software"), to deal 62 # in the Software without restriction, including without limitation the rights 63 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 64 # copies of the Software, and to permit persons to whom the Software is 65 # furished to do so, subject to the following conditions: 66 # 67 # The above copyright notice and this permission notice shall be included in 68 # all copies or substantial portions of the Software. 69 # 70 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 71 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 72 # FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 73 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 74 # LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 75 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 76 # THE SOFTWARE. 77 # 78 ******************************************************************************/ 79 #include "EPD_2in9.h" 80 #include "Debug.h" 81 82 const unsigned char EPD_2IN9_lut_full_update[] = { 83 0x50, 0xAA, 0x55, 0xAA, 0x11, 0x00, 84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 86 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 88 }; 89 90 const unsigned char EPD_2IN9_lut_partial_update[] = { 91 0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 92 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 94 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, 95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 96 }; 97 98 99 /****************************************************************************** 100 function : Software reset 101 parameter: 102 ******************************************************************************/ 103 static void EPD_2IN9_Reset(void) 104 { 105 DEV_Digital_Write(EPD_RST_PIN, 1); 106 DEV_Delay_ms(200); 107 DEV_Digital_Write(EPD_RST_PIN, 0); 108 DEV_Delay_ms(200); 109 DEV_Digital_Write(EPD_RST_PIN, 1); 110 DEV_Delay_ms(200); 111 } 112 113 /****************************************************************************** 114 function : send command 115 parameter: 116 Reg : Command register 117 ******************************************************************************/ 118 static void EPD_2IN9_SendCommand(UBYTE Reg) 119 { 120 DEV_Digital_Write(EPD_DC_PIN, 0); 121 DEV_Digital_Write(EPD_CS_PIN, 0); 122 DEV_SPI_WriteByte(Reg); 123 DEV_Digital_Write(EPD_CS_PIN, 1); 124 } 125 126 /****************************************************************************** 127 function : send data 128 parameter: 129 Data : Write data 130 ******************************************************************************/ 131 static void EPD_2IN9_SendData(UBYTE Data) 132 { 133 DEV_Digital_Write(EPD_DC_PIN, 1); 134 DEV_Digital_Write(EPD_CS_PIN, 0); 135 DEV_SPI_WriteByte(Data); 136 DEV_Digital_Write(EPD_CS_PIN, 1); 137 } 138 139 /****************************************************************************** 140 function : Wait until the busy_pin goes LOW 141 parameter: 142 ******************************************************************************/ 143 void EPD_2IN9_ReadBusy(void) 144 { 145 Debug("e-Paper busy\r\n"); 146 DEV_Delay_ms(100); 147 while(DEV_Digital_Read(EPD_BUSY_PIN) == 1) { //LOW: idle, HIGH: busy 148 DEV_Delay_ms(100); 149 } 150 Debug("e-Paper busy release\r\n"); 151 } 152 153 /****************************************************************************** 154 function : Setting the display window 155 parameter: 156 ******************************************************************************/ 157 static void EPD_2IN9_SetWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend) 158 { 159 EPD_2IN9_SendCommand(0x44); // SET_RAM_X_ADDRESS_START_END_POSITION 160 EPD_2IN9_SendData((Xstart >> 3) & 0xFF); 161 EPD_2IN9_SendData((Xend >> 3) & 0xFF); 162 163 EPD_2IN9_SendCommand(0x45); // SET_RAM_Y_ADDRESS_START_END_POSITION 164 EPD_2IN9_SendData(Ystart & 0xFF); 165 EPD_2IN9_SendData((Ystart >> 8) & 0xFF); 166 EPD_2IN9_SendData(Yend & 0xFF); 167 EPD_2IN9_SendData((Yend >> 8) & 0xFF); 168 } 169 170 /****************************************************************************** 171 function : Set Cursor 172 parameter: 173 ******************************************************************************/ 174 static void EPD_2IN9_SetCursor(UWORD Xstart, UWORD Ystart) 175 { 176 EPD_2IN9_SendCommand(0x4E); // SET_RAM_X_ADDRESS_COUNTER 177 EPD_2IN9_SendData((Xstart >> 3) & 0xFF); 178 179 EPD_2IN9_SendCommand(0x4F); // SET_RAM_Y_ADDRESS_COUNTER 180 EPD_2IN9_SendData(Ystart & 0xFF); 181 EPD_2IN9_SendData((Ystart >> 8) & 0xFF); 182 } 183 184 /****************************************************************************** 185 function : Turn On Display 186 parameter: 187 ******************************************************************************/ 188 static void EPD_2IN9_TurnOnDisplay(void) 189 { 190 EPD_2IN9_SendCommand(0x22); // DISPLAY_UPDATE_CONTROL_2 191 EPD_2IN9_SendData(0xC4); 192 EPD_2IN9_SendCommand(0x20); // MASTER_ACTIVATION 193 EPD_2IN9_SendCommand(0xFF); // TERMINATE_FRAME_READ_WRITE 194 195 EPD_2IN9_ReadBusy(); 196 } 197 198 /****************************************************************************** 199 function : Initialize the e-Paper register 200 parameter: 201 ******************************************************************************/ 202 void EPD_2IN9_Init(UBYTE Mode) 203 { 204 EPD_2IN9_Reset(); 205 206 EPD_2IN9_SendCommand(0x01); // DRIVER_OUTPUT_CONTROL 207 EPD_2IN9_SendData((EPD_2IN9_HEIGHT - 1) & 0xFF); 208 EPD_2IN9_SendData(((EPD_2IN9_HEIGHT - 1) >> 8) & 0xFF); 209 EPD_2IN9_SendData(0x00); // GD = 0; SM = 0; TB = 0; 210 211 EPD_2IN9_SendCommand(0x0C); // BOOSTER_SOFT_START_CONTROL 212 EPD_2IN9_SendData(0xD7); 213 EPD_2IN9_SendData(0xD6); 214 EPD_2IN9_SendData(0x9D); 215 216 EPD_2IN9_SendCommand(0x2C); // WRITE_VCOM_REGISTER 217 EPD_2IN9_SendData(0xA8); // VCOM 7C 218 219 EPD_2IN9_SendCommand(0x3A); // SET_DUMMY_LINE_PERIOD 220 EPD_2IN9_SendData(0x1A); // 4 dummy lines per gate 221 222 EPD_2IN9_SendCommand(0x3B); // SET_GATE_TIME 223 EPD_2IN9_SendData(0x08); // 2us per line 224 225 EPD_2IN9_SendCommand(0x3C); // BORDER_WAVEFORM_CONTROL 226 EPD_2IN9_SendData(0x03); 227 EPD_2IN9_SendCommand(0x11); // DATA_ENTRY_MODE_SETTING 228 EPD_2IN9_SendData(0x03); 229 230 //set the look-up table register 231 EPD_2IN9_SendCommand(0x32); // WRITE_LUT_REGISTER 232 if(Mode == EPD_2IN9_FULL){ 233 for (UWORD i = 0; i < 30; i++) { 234 EPD_2IN9_SendData(EPD_2IN9_lut_full_update[i]); 235 } 236 }else if(Mode == EPD_2IN9_PART){ 237 for (UWORD i = 0; i < 30; i++) { 238 EPD_2IN9_SendData(EPD_2IN9_lut_partial_update[i]); 239 } 240 }else{ 241 Debug("error, the Mode is EPD_2IN9_FULL or EPD_2IN9_PART"); 242 } 243 } 244 245 /****************************************************************************** 246 function : Clear screen 247 parameter: 248 ******************************************************************************/ 249 void EPD_2IN9_Clear(void) 250 { 251 UWORD Width, Height; 252 Width = (EPD_2IN9_WIDTH % 8 == 0)? (EPD_2IN9_WIDTH / 8 ): (EPD_2IN9_WIDTH / 8 + 1); 253 Height = EPD_2IN9_HEIGHT; 254 EPD_2IN9_SetWindows(0, 0, EPD_2IN9_WIDTH, EPD_2IN9_HEIGHT); 255 for (UWORD j = 0; j < Height; j++) { 256 EPD_2IN9_SetCursor(0, j); 257 EPD_2IN9_SendCommand(0x24); 258 for (UWORD i = 0; i < Width; i++) { 259 EPD_2IN9_SendData(0XFF); 260 } 261 } 262 EPD_2IN9_TurnOnDisplay(); 263 } 264 265 /****************************************************************************** 266 function : Sends the image buffer in RAM to e-Paper and displays 267 parameter: 268 ******************************************************************************/ 269 void EPD_2IN9_Display(UBYTE *Image) 270 { 271 UWORD Width, Height; 272 Width = (EPD_2IN9_WIDTH % 8 == 0)? (EPD_2IN9_WIDTH / 8 ): (EPD_2IN9_WIDTH / 8 + 1); 273 Height = EPD_2IN9_HEIGHT; 274 275 UDOUBLE Addr = 0; 276 // UDOUBLE Offset = ImageName; 277 EPD_2IN9_SetWindows(0, 0, EPD_2IN9_WIDTH, EPD_2IN9_HEIGHT); 278 for (UWORD j = 0; j < Height; j++) { 279 EPD_2IN9_SetCursor(0, j); 280 EPD_2IN9_SendCommand(0x24); 281 for (UWORD i = 0; i < Width; i++) { 282 Addr = i + j * Width; 283 EPD_2IN9_SendData(Image[Addr]); 284 } 285 } 286 EPD_2IN9_TurnOnDisplay(); 287 } 288 289 /****************************************************************************** 290 function : Enter sleep mode 291 parameter: 292 ******************************************************************************/ 293 void EPD_2IN9_Sleep(void) 294 { 295 EPD_2IN9_SendCommand(0x10); 296 EPD_2IN9_SendData(0x01); 297 // EPD_2IN9_ReadBusy(); 298 }