Gerrit Pathuis / Mbed 2 deprecated Epaper_epd1in54_Waveshare

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers epd1in54.cpp Source File

epd1in54.cpp

00001 /**
00002  *  @filename   :   epd1in54.cpp
00003  *  @brief      :   Implements for e-paper library
00004  *  @author     :   Yehui from Waveshare
00005  *
00006  *  Copyright (C) Waveshare     September 5 2017
00007  *
00008  * Permission is hereby granted, free of charge, to any person obtaining a copy
00009  * of this software and associated documnetation files (the "Software"), to deal
00010  * in the Software without restriction, including without limitation the rights
00011  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00012  * copies of the Software, and to permit persons to  whom the Software is
00013  * furished to do so, subject to the following conditions:
00014  *
00015  * The above copyright notice and this permission notice shall be included in
00016  * all copies or substantial portions of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00019  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00020  * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00021  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00022  * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00023  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00024  * THE SOFTWARE.
00025  */
00026 
00027 #include "epd1in54.h"
00028 
00029 extern Serial pc;
00030 
00031 Epd::~Epd()
00032 {
00033 };
00034 
00035 Epd::Epd()
00036 {
00037     reset_pin_no= 0;
00038     dc_pin_no = 1;
00039     cs_pin_no = 2;
00040     busy_pin_no = 3;
00041     width = EPD_WIDTH;
00042     height = EPD_HEIGHT;
00043 };
00044 
00045 int Epd::Init(const unsigned char* lut)
00046 {
00047     pc.printf("Init...  \n\r");
00048     /* this calls the peripheral hardware interface, see epdif */
00049     if (IfInit() != 0) {
00050         return -1;
00051     }
00052     /* EPD hardware init start */
00053     this->lut = lut;
00054     Reset();
00055     SendCommand(DRIVER_OUTPUT_CONTROL);
00056     SendData((EPD_HEIGHT - 1) & 0xFF);
00057     SendData(((EPD_HEIGHT - 1) >> 8) & 0xFF);
00058     SendData(0x00);                     // GD = 0; SM = 0; TB = 0;
00059     SendCommand(BOOSTER_SOFT_START_CONTROL);
00060     SendData(0xD7);
00061     SendData(0xD6);
00062     SendData(0x9D);
00063     SendCommand(WRITE_VCOM_REGISTER);
00064     SendData(0xA8);                     // VCOM 7C
00065     SendCommand(SET_DUMMY_LINE_PERIOD);
00066     SendData(0x1A);                     // 4 dummy lines per gate
00067     SendCommand(SET_GATE_TIME);
00068     SendData(0x08);                     // 2us per line
00069     SendCommand(DATA_ENTRY_MODE_SETTING);
00070     SendData(0x03);                     // X increment; Y increment
00071     SetLut(this->lut);
00072     /* EPD hardware init end */
00073     pc.printf("Init done \n\r");
00074     return 0;
00075 }
00076 
00077 /**
00078  *  @brief: basic function for sending commands
00079  */
00080 void Epd::SendCommand(unsigned char command)
00081 {
00082     DigitalWrite(dc_pin_no, LOW);
00083     SpiTransfer(command);
00084 }
00085 
00086 /**
00087  *  @brief: basic function for sending data
00088  */
00089 void Epd::SendData(unsigned char data)
00090 {
00091     DigitalWrite(dc_pin_no, HIGH);
00092     SpiTransfer(data);
00093 }
00094 
00095 
00096 /**
00097  *  @brief: Wait until the busy_pin goes LOW
00098  */
00099 void Epd::WaitUntilIdle(void)
00100 {
00101     while(DigitalRead(busy_pin_no) == HIGH) {      //LOW: idle, HIGH: busy
00102         DelayMs(100);
00103     }
00104 }
00105 
00106 /**
00107  *  @brief: module reset.
00108  *          often used to awaken the module in deep sleep,
00109  *          see Epd::Sleep();
00110  */
00111 void Epd::Reset(void)
00112 {
00113     DigitalWrite(reset_pin_no, LOW);                //module reset
00114     DelayMs(200);
00115     DigitalWrite(reset_pin_no, HIGH);
00116     DelayMs(200);
00117 }
00118 
00119 /**
00120  *  @brief: set the look-up table register
00121  */
00122 void Epd::SetLut(const unsigned char* lut)
00123 {
00124     this->lut = lut;
00125     SendCommand(WRITE_LUT_REGISTER);
00126     /* the length of look-up table is 30 bytes */
00127     for (int i = 0; i < 30; i++) {
00128         SendData(this->lut[i]);
00129     }
00130 }
00131 
00132 /**
00133  *  @brief: put an image buffer to the frame memory.
00134  *          this won't update the display.
00135  */
00136 void Epd::SetFrameMemory(
00137     const unsigned char* image_buffer,
00138     int x,int y, int image_width, int image_height)
00139 {
00140     int x_end;
00141     int y_end;
00142 
00143     if (
00144         image_buffer == NULL ||
00145         x < 0 || image_width < 0 ||
00146         y < 0 || image_height < 0
00147     ) {
00148         return;
00149     }
00150     /* x point must be the multiple of 8 or the last 3 bits will be ignored */
00151     x &= 0xF8;
00152     image_width &= 0xF8;
00153     if (x + image_width >= this->width) {
00154         x_end = this->width - 1;
00155     } else {
00156         x_end = x + image_width - 1;
00157     }
00158     if (y + image_height >= this->height) {
00159         y_end = this->height - 1;
00160     } else {
00161         y_end = y + image_height - 1;
00162     }
00163     SetMemoryArea(x, y, x_end, y_end);
00164     SetMemoryPointer(x, y);
00165     SendCommand(WRITE_RAM);
00166     /* send the image data */
00167     for (int j = 0; j < y_end - y + 1; j++) {
00168         for (int i = 0; i < (x_end - x + 1) / 8; i++) {
00169             SendData(image_buffer[i + j * (image_width / 8)]);
00170         }
00171     }
00172 }
00173 
00174 /**
00175  *  @brief: put an image buffer to the frame memory.
00176  *          this won't update the display.
00177  *
00178  *          Question: When do you use this function instead of
00179  *          void SetFrameMemory(
00180  *              const unsigned char* image_buffer,
00181  *              int x,
00182  *              int y,
00183  *              int image_width,
00184  *              int image_height
00185  *          );
00186  *          Answer: SetFrameMemory with parameters only reads image data
00187  *          from the RAM but not from the flash in AVR chips (for AVR chips,
00188  *          you have to use the function pgm_read_byte to read buffers
00189  *          from the flash).
00190  */
00191 void Epd::SetFrameMemory(const unsigned char* image_buffer)
00192 {
00193     SetMemoryArea(0, 0, this->width - 1, this->height - 1);
00194     SetMemoryPointer(0, 0);
00195     SendCommand(WRITE_RAM);
00196     /* send the image data */
00197     for (int i = 0; i < this->width / 8 * this->height; i++) {
00198         SendData(*(&image_buffer[i]));
00199     }
00200 }
00201 
00202 /**
00203  *  @brief: clear the frame memory with the specified color.
00204  *          this won't update the display.
00205  */
00206 void Epd::ClearFrameMemory(unsigned char color)
00207 {
00208     SetMemoryArea(0, 0, this->width - 1, this->height - 1);
00209     SetMemoryPointer(0, 0);
00210     SendCommand(WRITE_RAM);
00211 
00212     /* send the color data */
00213     for (int i = 0; i < this->width / 8 * this->height; i++) {
00214         SendData(color);
00215     }
00216 }
00217 
00218 /**
00219  *  @brief: update the display
00220  *          there are 2 memory areas embedded in the e-paper display
00221  *          but once this function is called,
00222  *          the the next action of SetFrameMemory or ClearFrame will
00223  *          set the other memory area.
00224  */
00225 void Epd::DisplayFrame(void)
00226 {
00227     SendCommand(DISPLAY_UPDATE_CONTROL_2);
00228     SendData(0xC4);
00229     SendCommand(MASTER_ACTIVATION);
00230     SendCommand(TERMINATE_FRAME_READ_WRITE);
00231     WaitUntilIdle();
00232 }
00233 
00234 /**
00235  *  @brief: private function to specify the memory area for data R/W
00236  */
00237 void Epd::SetMemoryArea(int x_start, int y_start, int x_end, int y_end)
00238 {
00239     SendCommand(SET_RAM_X_ADDRESS_START_END_POSITION);
00240     /* x point must be the multiple of 8 or the last 3 bits will be ignored */
00241     SendData((x_start >> 3) & 0xFF);
00242     SendData((x_end >> 3) & 0xFF);
00243     SendCommand(SET_RAM_Y_ADDRESS_START_END_POSITION);
00244     SendData(y_start & 0xFF);
00245     SendData((y_start >> 8) & 0xFF);
00246     SendData(y_end & 0xFF);
00247     SendData((y_end >> 8) & 0xFF);
00248 }
00249 
00250 /**
00251  *  @brief: private function to specify the start point for data R/W
00252  */
00253 void Epd::SetMemoryPointer(int x, int y)
00254 {
00255     SendCommand(SET_RAM_X_ADDRESS_COUNTER);
00256 
00257     /* x point must be the multiple of 8 or the last 3 bits will be ignored */
00258     SendData((x >> 3) & 0xFF);
00259     SendCommand(SET_RAM_Y_ADDRESS_COUNTER);
00260     SendData(y & 0xFF);
00261     SendData((y >> 8) & 0xFF);
00262     WaitUntilIdle();
00263 }
00264 
00265 /**
00266  *  @brief: After this command is transmitted, the chip would enter the
00267  *          deep-sleep mode to save power.
00268  *          The deep sleep mode would return to standby by hardware reset.
00269  *          You can use Epd::Init() to awaken
00270  */
00271 void Epd::Sleep()
00272 {
00273     SendCommand(DEEP_SLEEP_MODE);
00274     WaitUntilIdle();
00275 }
00276 
00277 const unsigned char lut_full_update[] = {
00278     0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22,
00279     0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88,
00280     0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51,
00281     0x35, 0x51, 0x51, 0x19, 0x01, 0x00
00282 };
00283 
00284 const unsigned char lut_partial_update[] = {
00285     0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00,
00286     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00287     0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12,
00288     0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00289 };
00290 
00291 
00292 /* END OF FILE */
00293 
00294 
00295