EA OLED (Orig. by SFord, retouched by Lerche)

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EAOLED.cpp Source File

EAOLED.cpp

00001 // test library for Embedded Artists OLED used on Xpresso Baseboard
00002 
00003 #include "EAOLED.h"
00004 #include "mbed.h"
00005 
00006 EAOLED::EAOLED(PinName mosi, PinName dnc, PinName sclk, PinName cs, PinName power) 
00007     : _spi(mosi, NC, sclk), _data(dnc), _cs(cs), _power(power) {
00008     reset();    
00009 }
00010       
00011 void EAOLED::command(int value) {
00012     _data = 0;
00013     _cs = 0;
00014     _spi.write(value);
00015     _cs = 1;
00016 }
00017 
00018 void EAOLED::data(int value) {
00019     _data = 1;
00020     _cs = 0;
00021     _spi.write(value);
00022     _cs = 1;
00023 }
00024 
00025 void EAOLED::reset() {
00026     _power = 0;
00027     _cs = 1;
00028 
00029     // Startup sequence recommended by embedded artists baseboard reference code
00030     command(0x02); // set low column address
00031     command(0x12); // set high column address
00032     command(0x40); // display start set
00033     command(0x2e); // stop horzontal scroll
00034     command(0x81); // set contrast control register
00035     command(0x32); //
00036     command(0x82); // brightness for color banks
00037     command(0x80); // display on
00038     command(0xa1); // set segment re-map
00039     command(0xa6); // set normal/inverse display
00040     command(0xa8); // set multiplex ratio
00041     command(0x3F); //
00042     command(0xd3); // set display offset
00043     command(0x40); //
00044     command(0xad); // set dc-dc on/off
00045     command(0x8E); //
00046     command(0xc8); // set com output scan direction
00047     command(0xd5); // set display clock divide ratio/oscillator/frequency
00048     command(0xf0); //
00049     command(0xd8); // set area color mode on/off & low power display mode 
00050     command(0x05); //
00051     command(0xd9); // set pre-charge period
00052     command(0xF1); //
00053     command(0xda); // set com pins hardware configuration
00054     command(0x12); //
00055     command(0xdb); // set vcom deselect level
00056     command(0x34); //
00057     command(0x91); // set look up table for area color 
00058     command(0x3f); //
00059     command(0x3f); //
00060     command(0x3f); //
00061     command(0x3f); //
00062     command(0xaf); // display on
00063     command(0xa4); // display on
00064 
00065     wait_us(10);
00066 
00067     _power = 1;
00068 }
00069 
00070 #define OLED_DISPLAY_WIDTH  96
00071 #define OLED_DISPLAY_HEIGHT 64
00072 
00073 void EAOLED::pixel(int x, int y, int colour) {
00074     int page = y >> 3;
00075     int address = 18 + x;
00076     
00077     int lo = (address >> 0) & 0x0F;
00078     int hi =  (address >> 4) | 0x10;
00079     int mask = 1 << (y & 0x7);
00080     int byte = page * OLED_DISPLAY_WIDTH + x;
00081     
00082     if(colour) {
00083         framebuffer[byte] |= mask;
00084     } else {
00085         framebuffer[byte] &= ~mask;
00086     }
00087 
00088     command(0xB0 + page);
00089     command(lo);
00090     command(hi);
00091     data(framebuffer[byte]);
00092 }
00093 
00094 void EAOLED::circle(int x0, int y0, int r, int colour) {
00095 
00096 #define OLED_DISPLAY_WIDTH  96
00097 #define OLED_DISPLAY_HEIGHT 64
00098 
00099     int draw_x0, draw_y0;
00100     int draw_x1, draw_y1;
00101     int draw_x2, draw_y2;
00102     int draw_x3, draw_y3;
00103     int draw_x4, draw_y4;
00104     int draw_x5, draw_y5;
00105     int draw_x6, draw_y6;
00106     int draw_x7, draw_y7;
00107     int xx, yy;
00108     int di;    
00109 
00110     if(r == 0)          /* no radius */
00111     {
00112         return;
00113     }
00114 
00115     draw_x0 = draw_x1 = x0;
00116     draw_y0 = draw_y1 = y0 + r;
00117     if(draw_y0 < OLED_DISPLAY_HEIGHT)
00118     {
00119         pixel(draw_x0, draw_y0, colour);     /* 90 degree */
00120     }
00121 
00122     draw_x2 = draw_x3 = x0;
00123     draw_y2 = draw_y3 = y0 - r;
00124     if(draw_y2 >= 0)
00125     {
00126         pixel(draw_x2, draw_y2, colour);    /* 270 degree */
00127     }
00128     
00129     draw_x4 = draw_x6 = x0 + r;
00130     draw_y4 = draw_y6 = y0;
00131     if(draw_x4 < OLED_DISPLAY_WIDTH)
00132     {
00133         pixel(draw_x4, draw_y4, colour);     /* 0 degree */
00134     }    
00135     
00136     draw_x5 = draw_x7 = x0 - r;
00137     draw_y5 = draw_y7 = y0;
00138     if(draw_x5>=0)
00139     {
00140         pixel(draw_x5, draw_y5, colour);     /* 180 degree */
00141     }
00142         
00143     if(r == 1)
00144     {
00145         return;
00146     }    
00147     
00148     di = 3 - 2*r;
00149     xx = 0;
00150     yy = r;
00151     while(xx < yy)
00152     {
00153 
00154         if(di < 0)
00155         {
00156             di += 4*xx + 6;
00157         }
00158         else
00159         {
00160             di += 4*(xx - yy) + 10;
00161             yy--;
00162             draw_y0--;
00163             draw_y1--;
00164             draw_y2++;
00165             draw_y3++;
00166             draw_x4--;
00167             draw_x5++;
00168             draw_x6--;
00169             draw_x7++;
00170         }
00171         xx++;
00172         draw_x0++;
00173         draw_x1--;
00174         draw_x2++;
00175         draw_x3--;
00176         draw_y4++;
00177         draw_y5++;
00178         draw_y6--;
00179         draw_y7--;
00180 
00181         if( (draw_x0 <= OLED_DISPLAY_WIDTH) && (draw_y0>=0) )
00182         {
00183             pixel(draw_x0, draw_y0, colour);
00184         }
00185 
00186         if( (draw_x1 >= 0) && (draw_y1 >= 0) )
00187         {
00188             pixel(draw_x1, draw_y1, colour);
00189         }
00190 
00191         if( (draw_x2 <= OLED_DISPLAY_WIDTH) && (draw_y2 <= OLED_DISPLAY_HEIGHT) )
00192         {
00193             pixel(draw_x2, draw_y2, colour);
00194         }
00195 
00196         if( (draw_x3 >=0 ) && (draw_y3 <= OLED_DISPLAY_HEIGHT) )
00197         {
00198             pixel(draw_x3, draw_y3, colour);
00199         }
00200 
00201         if( (draw_x4 <= /*OLED_DISPLAY_HEIGHT*/OLED_DISPLAY_WIDTH) && (draw_y4 >= 0) )
00202         {
00203             pixel(draw_x4, draw_y4, colour);
00204         }
00205 
00206         if( (draw_x5 >= 0) && (draw_y5 >= 0) )
00207         {
00208             pixel(draw_x5, draw_y5, colour);
00209         }
00210         if( (draw_x6 <= OLED_DISPLAY_WIDTH) && (draw_y6 <= OLED_DISPLAY_HEIGHT) )
00211         {
00212             pixel(draw_x6, draw_y6, colour);
00213         }
00214         if( (draw_x7 >= 0) && (draw_y7 <= OLED_DISPLAY_HEIGHT) )
00215         {
00216             pixel(draw_x7, draw_y7, colour);
00217         }
00218     }
00219     return;
00220 }
00221 
00222 void EAOLED::hline(int x0, int x1, int y, int colour) {
00223     for(int x=x0; x<x1; x++){
00224         pixel(x, y, colour);
00225     }
00226     return;
00227 }
00228 
00229 void EAOLED::vline(int y0, int y1, int x, int colour) {
00230     for(int y=y0; y<y1; y++){
00231         pixel(x, y, colour);
00232     }
00233     return;
00234 }
00235 
00236 void EAOLED::line(int x0, int y0, int x1, int y1, int colour) {
00237     int   dx = 0, dy = 0;
00238     int   dx_sym = 0, dy_sym = 0;
00239     int   dx_x2 = 0, dy_x2 = 0;
00240     int   di = 0;
00241 
00242     dx = x1-x0;
00243     dy = y1-y0;
00244 
00245 
00246     if(dx == 0)           /* vertical line */
00247     {
00248         for(int y=y0; y<y1; y++){
00249             pixel(x0, y, colour);
00250         }
00251         return;
00252     }
00253 
00254     if(dx > 0)
00255     {
00256         dx_sym = 1;
00257     }
00258     else
00259     {
00260         dx_sym = -1;
00261     }
00262 
00263 
00264     if(dy == 0)           /* horizontal line */
00265     {
00266         for(int x=x0; x<x1; x++){
00267             pixel(x, y0, colour);
00268         }
00269         return;
00270     }
00271 
00272 
00273     if(dy > 0)
00274     {
00275         dy_sym = 1;
00276     }
00277     else
00278     {
00279         dy_sym = -1;
00280     }
00281 
00282     dx = dx_sym*dx;
00283     dy = dy_sym*dy;
00284 
00285     dx_x2 = dx*2;
00286     dy_x2 = dy*2;
00287 
00288     if(dx >= dy)
00289     {
00290         di = dy_x2 - dx;
00291         while(x0 != x1)
00292         {
00293 
00294             pixel(x0, y0, colour);
00295             x0 += dx_sym;
00296             if(di<0)
00297             {
00298                 di += dy_x2;
00299             }
00300             else
00301             {
00302                 di += dy_x2 - dx_x2;
00303                 y0 += dy_sym;
00304             }
00305         }
00306         pixel(x0, y0, colour);
00307     }
00308     else
00309     {
00310         di = dx_x2 - dy;
00311         while(y0 != y1)
00312         {
00313             pixel(x0, y0, colour);
00314             y0 += dy_sym;
00315             if(di < 0)
00316             {
00317                 di += dx_x2;
00318             }
00319             else
00320             {
00321                 di += dx_x2 - dy_x2;
00322                 x0 += dx_sym;
00323             }
00324         }
00325         pixel(x0, y0, colour);
00326     }
00327     return;
00328 }
00329 
00330 void EAOLED::rect(int x0, int y0, int x1, int y1, int colour) {
00331 
00332     for(int x=x0; x<x1; x++){
00333         pixel(x, y0, colour);
00334     }
00335     for(int x=x0; x<x1; x++){
00336         pixel(x, y1, colour);
00337     }
00338     for(int y=y0; y<y1; y++){
00339         pixel(x0, y, colour);
00340     }
00341     for(int y=y0; y<y1; y++){
00342         pixel(x1, y, colour);
00343     }
00344     return;
00345 }
00346 
00347 void EAOLED::fillrect(int x0, int y0, int x1, int y1, int colour) {
00348 
00349     int i = 0;
00350 
00351     if(x0 > x1)
00352     {
00353         i  = x0;
00354         x0 = x1;
00355         x1 = i;
00356     }
00357 
00358     if(y0 > y1)
00359     {
00360         i  = y0;
00361         y0 = y1;
00362         y1 = i;
00363     }
00364 
00365     if(y0 == y1)
00366     {
00367         for(int x=x0; x<x1; x++){
00368             pixel(x, y0, colour);
00369         }
00370         return;
00371     }
00372 
00373     if(x0 == x1)
00374     {
00375         for(int y=y0; y<y1; y++){
00376             pixel(x0, y, colour);
00377         }
00378         return;
00379     }
00380 
00381     while(y0 <= y1)
00382     {
00383         for(int x=x0; x<x1; x++){
00384             pixel(x, y0, colour);
00385         }
00386         y0++;
00387     }
00388     return;
00389 
00390 }