tempcommit 13/05

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers epd4in2b.cpp Source File

epd4in2b.cpp

00001 /**
00002  *  @filename   :   epd4in2b.cpp
00003  *  @brief      :   Implements for Dual-color e-paper library
00004  *  @author     :   Yehui from Waveshare
00005  *
00006  *  Copyright (C) Waveshare     August 10 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 <stdlib.h>
00028 #include <epd4in2b.h>
00029 
00030 #include "mbed.h"
00031 #include "SPI.h"
00032 
00033 
00034 
00035 Epd::~Epd() {
00036 };
00037 
00038 //,dc_pin(D5),busy_pin(D3),reset_pin(A2),_cs_pin(D9)
00039 Epd::Epd():dc_pin(D5),busy_pin(D3),reset_pin(A2) {
00040     /*
00041     reset_pin = RST_PIN;
00042     dc_pin = DC_PIN;
00043     cs_pin = CS_PIN;
00044     busy_pin = BUSY_PIN;
00045     */
00046     width = EPD_WIDTH;
00047     height = EPD_HEIGHT;
00048 };
00049 
00050 int Epd::Init(void) {
00051     printf("start init \r\n");
00052     /* this calls the peripheral hardware interface, see epdif */
00053     if (IfInit() != 0) {
00054         printf("interface init kapot \r\n");
00055         return -1;
00056     }
00057     /* EPD hardware init start */
00058     printf("reset \r\n");
00059     Reset();
00060     printf("send command 1 \r\n");
00061     SendCommand(BOOSTER_SOFT_START);
00062     printf("send data \r\n");
00063     SendData(0x17);
00064     wait(1);
00065     SendData(0x17);
00066     SendData(0x17);     //07 0f 17 1f 27 2F 37 2f
00067     printf("send command 2 \r\n");
00068     SendCommand(POWER_ON);
00069     printf("pre wait \r\n");
00070     WaitUntilIdle();
00071     printf("post wait \r\n");
00072     SendCommand(PANEL_SETTING);
00073     SendData(0x0F);     // LUT from OTP
00074     /* EPD hardware init end */
00075     
00076     SendCommand(PLL_CONTROL);
00077     return 0;
00078 }
00079 
00080 /**
00081  *  @brief: basic function for sending commands
00082  */
00083 void Epd::SendCommand(unsigned char command) {
00084     //DigitalOut(dc_pin, LOW);
00085     dc_pin = 0;
00086     SpiTransfer(command);
00087 }
00088 
00089 /**
00090  *  @brief: basic function for sending data
00091  */
00092 void Epd::SendData(unsigned char data) {
00093     //DigitalOut(dc_pin, HIGH);
00094     dc_pin = 1;
00095     SpiTransfer(data);
00096 }
00097 
00098 /**
00099  *  @brief: Wait until the busy_pin goes HIGH
00100  */
00101 void Epd::WaitUntilIdle(void) {
00102     
00103     /*
00104     //in de while read uit epdif was eerst in gebruik
00105     //busy was 0
00106     while(busy_pin == 1) {      //0: busy, 1: idle
00107         DelayMs(100);
00108     }
00109     */
00110     wait (3);    
00111 }
00112 
00113 /**
00114  *  @brief: module reset. 
00115  *          often used to awaken the module in deep sleep, 
00116  *          see Epd::Sleep();
00117  */
00118 void Epd::Reset(void) {
00119     //DigitalOut(reset_pin, LOW);
00120     reset_pin = LOW;
00121     printf("pre delay \r\n");
00122     DelayMs(200);
00123     printf("post delay \r\n");
00124     //DigitalOut(reset_pin, HIGH);
00125     reset_pin = HIGH;
00126     DelayMs(200);   
00127 }
00128 
00129 /**
00130  *  @brief: transmit partial data to the SRAM
00131  */
00132 void Epd::SetPartialWindow(const unsigned char* buffer_black, const unsigned char* buffer_red, int x, int y, int w, int l) {
00133     SendCommand(PARTIAL_IN);
00134     SendCommand(PARTIAL_WINDOW);
00135     SendData(x >> 8);
00136     SendData(x & 0xf8);     // x should be the multiple of 8, the last 3 bit will always be ignored
00137     SendData(((x & 0xf8) + w  - 1) >> 8);
00138     SendData(((x & 0xf8) + w  - 1) | 0x07);
00139     SendData(y >> 8);        
00140     SendData(y & 0xff);
00141     SendData((y + l - 1) >> 8);        
00142     SendData((y + l - 1) & 0xff);
00143     SendData(0x01);         // Gates scan both inside and outside of the partial window. (default) 
00144     DelayMs(2);
00145     SendCommand(DATA_START_TRANSMISSION_1);
00146     if (buffer_black != NULL) {
00147         for(int i = 0; i < w  / 8 * l; i++) {
00148             SendData(buffer_black[i]);  
00149         }  
00150     }
00151     DelayMs(2);
00152     SendCommand(DATA_START_TRANSMISSION_2);
00153     if (buffer_red != NULL) {
00154         for(int i = 0; i < w  / 8 * l; i++) {
00155             SendData(buffer_red[i]);  
00156         }  
00157     }
00158     DelayMs(2);
00159     SendCommand(PARTIAL_OUT);  
00160 }
00161 
00162 /**
00163  *  @brief: transmit partial data to the black part of SRAM
00164  */
00165 void Epd::SetPartialWindowBlack(const unsigned char* buffer_black, int x, int y, int w, int l) {
00166     SendCommand(PARTIAL_IN);
00167     SendCommand(PARTIAL_WINDOW);
00168     SendData(x >> 8);
00169     SendData(x & 0xf8);     // x should be the multiple of 8, the last 3 bit will always be ignored
00170     SendData(((x & 0xf8) + w  - 1) >> 8);
00171     SendData(((x & 0xf8) + w  - 1) | 0x07);
00172     SendData(y >> 8);        
00173     SendData(y & 0xff);
00174     SendData((y + l - 1) >> 8);        
00175     SendData((y + l - 1) & 0xff);
00176     SendData(0x01);         // Gates scan both inside and outside of the partial window. (default) 
00177     DelayMs(2);
00178     SendCommand(DATA_START_TRANSMISSION_1);
00179     if (buffer_black != NULL) {
00180         for(int i = 0; i < w  / 8 * l; i++) {
00181             SendData(buffer_black[i]);  
00182         }  
00183     }
00184     DelayMs(2);
00185     SendCommand(PARTIAL_OUT);  
00186 }
00187 
00188 /**
00189  *  @brief: transmit partial data to the red part of SRAM
00190  */
00191 void Epd::SetPartialWindowRed(const unsigned char* buffer_red, int x, int y, int w, int l) {
00192     SendCommand(PARTIAL_IN);
00193     SendCommand(PARTIAL_WINDOW);
00194     SendData(x >> 8);
00195     SendData(x & 0xf8);     // x should be the multiple of 8, the last 3 bit will always be ignored
00196     SendData(((x & 0xf8) + w  - 1) >> 8);
00197     SendData(((x & 0xf8) + w  - 1) | 0x07);
00198     SendData(y >> 8);        
00199     SendData(y & 0xff);
00200     SendData((y + l - 1) >> 8);        
00201     SendData((y + l - 1) & 0xff);
00202     SendData(0x01);         // Gates scan both inside and outside of the partial window. (default) 
00203     DelayMs(2);
00204     SendCommand(DATA_START_TRANSMISSION_2);
00205     if (buffer_red != NULL) {
00206         for(int i = 0; i < w  / 8 * l; i++) {
00207             SendData(buffer_red[i]);  
00208         }  
00209     }
00210     DelayMs(2);
00211     SendCommand(PARTIAL_OUT);  
00212 }
00213 
00214 /**
00215  * @brief: refresh and displays the frame
00216  */
00217 void Epd::DisplayFrame(const unsigned char* frame_black, const unsigned char* frame_red) {
00218     if (frame_black != NULL) {
00219         SendCommand(DATA_START_TRANSMISSION_1);
00220         DelayMs(2);
00221         for (int i = 0; i < this->width / 8 * this->height; i++) {
00222             //SendData(pgm_read_byte(&frame_black[i]));
00223             SendData(frame_black[i]);
00224         }
00225         DelayMs(2);
00226     }
00227     if (frame_red != NULL) {
00228         SendCommand(DATA_START_TRANSMISSION_2);
00229         DelayMs(2);
00230         for (int i = 0; i < this->width / 8 * this->height; i++) {
00231             //SendData(pgm_read_byte(&frame_red[i]));
00232             SendData(frame_red[i]);
00233         }
00234         DelayMs(2);
00235     }
00236     SendCommand(DISPLAY_REFRESH);
00237     WaitUntilIdle();
00238 }
00239 
00240 /**
00241  * @brief: clear the frame data from the SRAM, this won't refresh the display
00242  */
00243 void Epd::ClearFrame(void) {
00244     SendCommand(DATA_START_TRANSMISSION_1);           
00245     DelayMs(2);
00246     for(int i = 0; i < width / 8 * height; i++) {
00247         SendData(0xFF);  
00248     }  
00249     DelayMs(2);
00250     SendCommand(DATA_START_TRANSMISSION_2);           
00251     DelayMs(2);
00252     for(int i = 0; i < width / 8 * height; i++) {
00253         SendData(0xFF);  
00254     }  
00255     DelayMs(2);
00256 }
00257 
00258 /**
00259  * @brief: This displays the frame data from SRAM
00260  */
00261 void Epd::DisplayFrame(void) {
00262     SendCommand(DISPLAY_REFRESH); 
00263     DelayMs(100);
00264     WaitUntilIdle();
00265 }
00266 
00267 /**
00268  * @brief: After this command is transmitted, the chip would enter the deep-sleep mode to save power. 
00269  *         The deep sleep mode would return to standby by hardware reset. The only one parameter is a 
00270  *         check code, the command would be executed if check code = 0xA5. 
00271  *         You can use Epd::Reset() to awaken and use Epd::Init() to initialize.
00272  */
00273 void Epd::Sleep() {
00274     SendCommand(VCOM_AND_DATA_INTERVAL_SETTING);
00275     SendData(0xF7);     // border floating
00276     SendCommand(POWER_OFF);
00277     WaitUntilIdle();
00278     SendCommand(DEEP_SLEEP);
00279     SendData(0xA5);     // check code
00280 }
00281 
00282 
00283 /* END OF FILE */
00284 
00285 
00286 
00287 
00288