EPD display library. Check this version (it should work)

Fork of GDEP015OC1 by Jurica Resetar

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GDEP015OC1.cpp Source File

GDEP015OC1.cpp

00001 /**
00002  *  Created by Filip Hormot (f.hormot@gmail.com) on 14/09/16.
00003  */
00004 #include "mbed.h"
00005 #include "GDEP015OC1.h"
00006 #include "5x7.h"
00007 
00008 #define EPD_WAIT_CONSTANT 10
00009 
00010 static const unsigned char _lutFull[] = { 
00011     0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22, 0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 
00012     0x88, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51, 0x35, 0x51, 0x51, 0x19, 0x01, 0x00
00013 };
00014 
00015 static const unsigned char _lutPart[] = {
00016     0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00017     0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00018 };
00019 
00020 GDEP015OC1::GDEP015OC1(SPI& spi, PinName cs=p5, PinName dc=p6, PinName rst=p7, PinName busy=p8) : _spi(spi), _cs(cs), _dc(dc), _rst(rst), _busy(busy){
00021     _bold = true;
00022     _italic = false;
00023     _init();
00024 }
00025 
00026 void GDEP015OC1::_spiCommand(unsigned char command){
00027     _cs = _dc = 0;
00028     wait_us(1);
00029     
00030     _spi.write(command);
00031 }
00032 
00033 void GDEP015OC1::_spiData(unsigned char data){
00034     _cs = 0;
00035     _dc = 1;
00036     wait_us(1);
00037     
00038     _spi.write(data);
00039 }
00040 
00041 void GDEP015OC1::_init(void){
00042     _rst = _cs = 1;
00043     empty();    
00044 }
00045 
00046 
00047 void GDEP015OC1::_wakeUp(bool partial){
00048     _rst = 0;
00049     wait_ms(EPD_WAIT_CONSTANT);
00050     _rst = 1;
00051     wait_ms(EPD_WAIT_CONSTANT);
00052     
00053     //Stage 3
00054     //Driver Output control
00055     _spiCommand(0x01);
00056     _spiData(0xC7);     // (yDot-1)%256
00057     _spiData(0x00);     // (yDot-1)/256
00058     _spiData(0x00);     // 0x00
00059     
00060     //Softstart
00061     _spiCommand(0x0C);
00062     _spiData(0xD7);
00063     _spiData(0xD6);
00064     _spiData(0x9D);
00065 
00066     //VCOM setting
00067     _spiCommand(0x2C);
00068     _spiData(0xA8);
00069     
00070     //Dummy line period
00071     _spiCommand(0x3A);
00072     _spiData(0x1A);
00073     
00074     //Gate line width // 2us per line
00075     _spiCommand(0x3B);
00076     _spiData(0x08);
00077     
00078     //Set data entry mode
00079     _spiCommand(0x11);
00080     _spiData(0x01); //DO NOT TOUCH THIS! (MUST BE 0x01)
00081     
00082     // ^--- Ovdje zavrsavana Kneska fca EPD_W21_DispInit
00083     
00084     
00085     /*
00086     // Clock
00087     _spiCommand(0x22);
00088     _spiData(0xF0);
00089     //VGH VGL
00090     _spiCommand(0x03);
00091     _spiData(0x00);
00092     //VSH, VSL
00093     _spiCommand(0x04);
00094     _spiData(0x0A);
00095     // Source voltage +15V/-15V
00096     _spiCommand(0xF0);
00097     _spiData(0x1F);
00098     //Gate driver start position
00099     _spiCommand(0x0F);
00100     _spiData(0x2B);
00101     _spiData(0x01);
00102     */
00103     
00104     
00105     
00106     
00107         
00108     
00109 
00110 
00111     //Define X display size
00112     _spiCommand(0x44);
00113     _spiData(0x00);
00114     _spiData(0x18);     //(xDot-1)/8
00115     //Define Y display size
00116     _spiCommand(0x45);
00117     _spiData(0xC7);     //(yDot-1)%256
00118     _spiData(0x00);     //(yDot-1)/256
00119     _spiData(0x00);     // Was 0x2B
00120     _spiData(0x00);     // Was 0x01
00121 
00122     //Define X RAM address
00123     _spiCommand(0x4E);
00124     _spiData(0x00);
00125     //Define Y RAM address
00126     _spiCommand(0x4F);
00127     _spiData(0xC7);
00128     _spiData(0x00);
00129 
00130 
00131     //Border waveform control
00132     //_spiCommand(0x3C);
00133     //_spiData(0x33);
00134     
00135     // ^---- Do ovuda je sve po Kinezima
00136 
00137     //Write LUT
00138     _spiCommand(0x32);
00139     if(partial){
00140         for(uint8_t i = 0; i<30;i++){
00141             _spiData(_lutPart[i]);
00142         }
00143     } else{
00144         for(uint8_t i = 0; i<30;i++){
00145             _spiData(_lutFull[i]);
00146         }
00147     }
00148 
00149     //Power on
00150     //_spiCommand(0x22);
00151     //_spiData(0xFF);
00152 
00153     //Define X RAM address
00154     //_spiCommand(0x4E);
00155     //_spiData(0x00);
00156     //Define Y RAM address
00157     //_spiCommand(0x4F);
00158     //_spiData(0xC7);
00159     //_spiData(0x00);
00160 }
00161 
00162 void GDEP015OC1::_sleep(void){
00163     while(_busy == BUSY_STATE);
00164 
00165     _spiCommand(0x10);
00166     _spiData(0x01);
00167 }
00168 
00169 /*  
00170  *  If you touch this function satan will feast on your soul for an eternity!
00171  *  IM NOT PLAYING AROUND DONT FUCKING TOUCH IT!
00172  *  You are thinking about it...
00173  *  .
00174  *  .
00175  *  .
00176  *  DONT!
00177  */
00178 unsigned char GDEP015OC1::_pixelConv(unsigned char *data, int i){
00179     uint8_t pix = 0x00;
00180     for(uint8_t x = 0; x < 8; x++){
00181         pix |= ((*(data + (i*200)%5000 + (24-i/200) + x*25)>>((i/25)%8))&(0x01))<<(7-x);
00182     }
00183     return pix^0xFF;    
00184 }
00185 
00186 uint8_t GDEP015OC1::_mirrorData(uint8_t data){
00187     uint8_t mirror = 0x00;
00188     for(uint8_t i=0; i<8; i++)
00189         mirror |= ((data>>i) & 0x01) << (7 - i);
00190 
00191     return mirror;
00192 }
00193 
00194 void GDEP015OC1::fill(unsigned char data, int x){
00195     _buffer[x] = data;   
00196 }
00197 
00198 void GDEP015OC1::empty(void){
00199     for(uint16_t x=0; x<5000; x++)
00200         _buffer[x] = 0x00;
00201 }
00202 
00203 void GDEP015OC1::write(void){
00204     _wakeUp(true);
00205 
00206     _spiCommand(0x24);
00207     for(int16_t x=0; x>=0 && x<200; x++){
00208         for(int16_t y=24; y>=0 && y<25; y--){
00209             _spiData(_mirrorData(_pixelConv(_buffer, x*25+y)));
00210             wait_us(EPD_WAIT_CONSTANT);
00211         }
00212     }
00213 
00214     _spiCommand(0x22);
00215     _spiData(0x04);
00216     _spiCommand(0x22);
00217     _spiData(0x08);
00218 
00219     //Update
00220     _spiCommand(0x22);
00221     _spiData(0xC7);
00222     _spiCommand(0x20);
00223 
00224     _sleep();
00225 }
00226 
00227 void GDEP015OC1::writeFull(void){
00228     _wakeUp(false);
00229 
00230     _spiCommand(0x24);
00231     for(int16_t x=0; x>=0 && x<200; x++){
00232         for(int16_t y=24; y>=0 && y<25; y--){
00233             _spiData(_mirrorData(_pixelConv(_buffer, x*25+y)));
00234             wait_us(EPD_WAIT_CONSTANT);
00235         }
00236     }
00237 
00238     _spiCommand(0x22);
00239     _spiData(0x04);
00240     _spiCommand(0x22);
00241     _spiData(0x08);
00242 
00243     //Update
00244     _spiCommand(0x22);
00245     _spiData(0xC7);
00246     _spiCommand(0x20);
00247 
00248     _sleep();
00249 }
00250 
00251 void GDEP015OC1::drawPixel(uint16_t startX, uint16_t startY, bool color=0){
00252     if(startX>199 || startY>199) return;
00253     
00254     uint16_t i = startX/8 + startY*25;
00255 
00256     if(!color)
00257         _buffer[i] = (_buffer[i] | (1<<(7-startX%8)));
00258     else
00259         _buffer[i] = (_buffer[i] & (0xFF^(1<<(7-startX%8))));
00260 }
00261 
00262 
00263 void GDEP015OC1::drawLine(uint16_t startX,  uint16_t startY, uint16_t stopX, uint16_t stopY, bool color=0){
00264     int dx = abs(stopX-startX), sx = startX<stopX ? 1 : -1;
00265     int dy = abs(stopY-startY), sy = startY<stopY ? 1 : -1;
00266     int err = (dx>dy ? dx : -dy)/2, e2;
00267     
00268     for(;;){
00269         drawPixel(startX,startY,color);
00270         if (startX==stopX && startY==stopY) break;
00271         e2 = err;
00272         if (e2 >-dx) { err -= dy; startX += sx; }
00273         if (e2 < dy) { err += dx; startY += sy; }
00274     }
00275 }
00276 
00277 void GDEP015OC1::drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, bool color=0){
00278     drawLine(x1, y1, x2, y2, color);
00279     drawLine(x2, y2, x3, y3, color);
00280     drawLine(x3, y3, x1, y1, color);      
00281 }
00282 
00283 void GDEP015OC1::drawRectangle(uint16_t startX, uint16_t startY, uint16_t stopX, uint16_t stopY, bool color=0){
00284     drawLine(startX, startY, stopX,  startY, color);
00285     drawLine(stopX,  startY, stopX,  stopY,  color);
00286     drawLine(stopX,  stopY,  startX, stopY,  color);
00287     drawLine(startX, stopY,  startX, startY, color);    
00288 }
00289 
00290 void GDEP015OC1::drawCircle(uint16_t startX, uint16_t startY, uint16_t radius, bool color=0){
00291     int d,x,y;
00292 
00293     d=3-2*radius;
00294     x=0;
00295     y=radius;
00296     while(x<=y){
00297         drawPixel(startX+x,startY+y,color);
00298         drawPixel(startX-y,startY-x,color);
00299         drawPixel(startX+y,startY-x,color);
00300         drawPixel(startX-y,startY+x,color);
00301         drawPixel(startX+y,startY+x,color);
00302         drawPixel(startX-x,startY-y,color);
00303         drawPixel(startX+x,startY-y,color);
00304         drawPixel(startX-x,startY+y,color);
00305 
00306         if(d<=0)
00307             d=d+4*x+6;
00308         else{
00309             d=d+4*x-4*y+10;
00310             y--;
00311         }
00312         x++;
00313     }
00314 }
00315 
00316 void GDEP015OC1::fillCircle(uint16_t startX, uint16_t startY, uint16_t radius, bool color=0){
00317     for(uint16_t r = 1;r<=radius; r++){
00318         drawCircle(startX,   startY, r,   color);
00319         drawCircle(startX+1, startY, r-1, color);
00320         drawCircle(startX-1, startY, r-1, color);
00321     }
00322 }
00323 
00324 void GDEP015OC1::drawEllipse(uint16_t startX, uint16_t startY, uint16_t width, uint16_t height, bool color){
00325     int a2 = width*width;
00326     int b2 = height*height;
00327     int fa2 = 4*a2, fb2 = 4*b2;
00328     int x, y, sigma;
00329                                                         
00330   //First half                                                      
00331     for(int x = 0, y = height, sigma = 2*b2+a2*(1-2*height); b2*x <= a2*y; x++){
00332         drawPixel(startX+x,startY+y,color);
00333         drawPixel(startX-x,startY+y,color);
00334         drawPixel(startX+x,startY-y,color);
00335         drawPixel(startX-x,startY-y,color);
00336         if(sigma >= 0){
00337             sigma += fa2 * (1-y);
00338             y--;
00339         }
00340         sigma += b2 * ((4 * x) + 6);
00341     }
00342     //Second half
00343     for (x = width, y = 0, sigma = 2*a2+b2*(1-2*width); a2*y <= b2*x; y++){
00344         drawPixel(startX+x,startY+y,color);
00345         drawPixel(startX-x,startY+y,color);
00346         drawPixel(startX+x,startY-y,color);
00347         drawPixel(startX-x,startY-y,color);
00348         if (sigma >= 0){
00349                 sigma += fb2 * (1 - x);
00350                 x--;
00351         }
00352         sigma += a2 * ((4 * y) + 6);
00353     }       
00354 }
00355 
00356 void GDEP015OC1::fillEllipse(uint16_t startX, uint16_t startY, uint16_t width, uint16_t height, bool color=0){
00357     for(uint16_t w = width; w > 0; w--){
00358         drawEllipse(startX, startX, w, height, color);
00359     }
00360     drawLine(startX, startY-height, startX, startY+height, color);
00361 }
00362 
00363 void GDEP015OC1::writeChar(char character, uint16_t startX, uint16_t startY, bool color=0){
00364     unsigned char letter[FONT_WIDTH];
00365 
00366     //Grab data for the corresponding font
00367     for(uint8_t i = 0; i<FONT_WIDTH; i++)
00368         letter[i] = Font5x7[(character - ' ') * FONT_WIDTH + i];
00369 
00370     for(uint8_t i = 0; i<FONT_WIDTH; i++){
00371         for(uint8_t j = 0; j<FONT_HEIGHT; j++){
00372             if((letter[i]>>j)&0x01){
00373                 if(_italic){
00374                     drawPixel(startX+i+(FONT_HEIGHT/3 - j/3), startY+j, color);
00375                     if(_bold){
00376                         for(uint8_t z=0; z<2; z++)
00377                             drawPixel(startX+i-z+(FONT_HEIGHT/3- j/3), startY+j, color);
00378                     }
00379                 }
00380                 else{
00381                     drawPixel(startX+i, startY+j, color);
00382                     if(_bold){
00383                         for(uint8_t z=0; z<2; z++)
00384                             drawPixel(startX+i-z, startY+j, color);
00385                     }
00386                 }
00387             }
00388         }
00389     }   
00390 }
00391 
00392 void GDEP015OC1::writeString(char *string, uint16_t startX, uint16_t startY, bool color=0){
00393     uint8_t length = 0;
00394     while(*(string+length) != '\0') length++;
00395     
00396     for(uint8_t x=0; x<length; x++)
00397         writeChar(*(string+x), startX+(FONT_WIDTH+1)*x, startY, color); //FONT_WIDTH+1 gives a 1px space between the characters
00398 }