Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers OLEDSeps525f.cpp Source File

OLEDSeps525f.cpp

00001 /* mbed Library - OLEDSeps525f
00002  * Copyright (c) 2010, sblandford
00003  * Based on MobileLCD library
00004  * Copyright (c) 2007/8, sford
00005  * released under MIT license http://mbed.org/licence/mit
00006  */
00007 
00008 #include "OLEDSeps525f.h"
00009 
00010 #include "mbed.h"
00011 
00012 //Serial pc1(USBTX, USBRX); // tx, rx
00013 
00014 
00015 using namespace mbed;
00016 OLEDSeps525f::OLEDSeps525f(PinName mosi, PinName miso, PinName clk, PinName cs, PinName rst, PinName rs)
00017         : _spi(mosi, miso, clk)
00018         , _cs(cs)
00019         , _rst(rst)
00020         , _rs(rs) {
00021     _row = 0;
00022     _column = 0;
00023     _width = _physical_width;
00024     _height = _physical_height;
00025     _rotation = 0;
00026     _columns = _width/8;
00027     _rows = _height/8;
00028     _tablength = 4;
00029     _writing_pixels = 0;
00030     foreground(0x00FFFFFF);
00031     background(0x00000000);
00032     reset();
00033 }
00034 
00035 void OLEDSeps525f::reset() {
00036 
00037     unsigned int i=0,j,k;
00038     const unsigned char init_commands[]= {
00039         0x06, // Display off
00040         0x00,
00041 
00042         //Osc control
00043         //Export1 internal clock and OSC operates with external resistor
00044         0x02,
00045         0x01,
00046 
00047         //Reduce current
00048         0x04,
00049         0x00,
00050 
00051         //Clock div ratio 1: freq setting 90Hz
00052         0x03,
00053         0x30,
00054 
00055         //Iref controlled by external resistor
00056         0x80,
00057         0x00,
00058 
00059         //Precharge time R
00060         0x08,
00061         0x01,
00062         //Precharge time G
00063         0x09,
00064         0x01,
00065         //Precharge time B
00066         0x0A,
00067         0x01,
00068 
00069         //Precharge current R
00070         0x0B,
00071         0x0A,
00072         //Precharge current G
00073         0x0C,
00074         0x0A,
00075         //Precharge current B
00076         0x0D,
00077         0x0A,
00078 
00079         //Driving current R = 82uA
00080         0x10,
00081         0x52,
00082         //Driving current G = 56uA
00083         0x11,
00084         0x38,
00085         //Driving current B = 58uA
00086         0x12,
00087         0x3A,
00088 
00089         //Display mode set
00090         //RGB,column=0-159, column data display=Normal display
00091         0x13,
00092         0x00,
00093 
00094         //External interface mode=MPU
00095         0x14,
00096         0x01,
00097 
00098         //Memory write mode
00099         //6 bits triple transfer, 262K support, Horizontal address counter is increased,
00100         //vertical address counter is increased. The data is continuously written
00101         //horizontally
00102         0x16,
00103         0x76,
00104 
00105         //Memory address setting range 0x17~0x19 to width x height
00106         0x17,  //Column start
00107         0x00,
00108         0x18,  //Column end
00109         _physical_width-1,
00110         0x19,  //row start
00111         0x00,
00112         0x1A,  //row end
00113         _physical_height-1,
00114 
00115         //Memory start address set to 0x20~0x21
00116         0x20,  //X
00117         0x00,
00118         0x21,  //Y
00119         0x00,
00120 
00121         //Duty
00122         0x29,
00123         0x00,
00124 
00125         //Display start line
00126         0x29,
00127         0x00,
00128 
00129         //DDRAM read address start point 0x2E~0x2F
00130         0x2E,  //X
00131         0x00,
00132         0x2F,  //Y
00133         0x00,
00134 
00135         //Display screen saver size 0x33~0x36
00136         0x33,  //Screen saver columns start
00137         0x00,
00138         0x34,  //Screen saver columns end
00139         _physical_width-1,
00140         0x35,  //screen saver row start
00141         0x00,
00142         0x36,  //Screen saver row end
00143         _physical_height-1,
00144 
00145         //Display ON
00146         0x06,
00147         0x01,
00148 
00149         //End of commands
00150         0xFF,
00151         0xFF
00152     };
00153 
00154     //Initialize interface and reset display driver chip
00155     _cs = 1;
00156     wait(0.01);
00157     _rst = 0;
00158     wait(0.001);
00159     _rst = 1;
00160     wait(0.01);
00161     _spi.format(8);
00162     _spi.frequency(10000000);
00163 
00164     //Send initialization commands
00165     for (i=0; ;i+=2) {
00166         j=(int)init_commands[i];
00167         k=(int)init_commands[i+1];
00168         if ((j==0xFF) && (k==0xFF)) break;
00169 
00170         command(j);
00171         data(k);
00172     }
00173 }
00174 
00175 void OLEDSeps525f::command(int value) {
00176 
00177     _writing_pixels=(value == 0x22);
00178     _rs = 0;
00179     _cs = 0;
00180     _spi.write(value);
00181     _cs = 1;
00182     _rs = 1;
00183 }
00184 
00185 void OLEDSeps525f::data(int value) {
00186     _rs = 1;
00187     _cs = 0;
00188     _spi.write(value);
00189     _cs = 1;
00190 }
00191 
00192 inline
00193 void OLEDSeps525f::rgbdot(int r, int g, int b)
00194 {
00195     _rs = 1;
00196     _cs = 0;
00197     _spi.write(r);
00198     _cs = 1;
00199     _cs = 0;    
00200     _spi.write(g);
00201     _cs = 1;
00202     _cs = 0;
00203     _spi.write(b);
00204     _cs = 1;
00205 }
00206 
00207 void OLEDSeps525f::_window(int x, int y, int width, int height) {
00208     int x1, x2, y1, y2, start_x, start_y;
00209     switch (_rotation) {
00210         default:
00211         case 0:
00212             x1 = x;
00213             y1 = y;
00214             x2 = x + width - 1;
00215             y2 = y + height - 1;
00216             break;
00217         case 1:
00218             x1 = _physical_width - y - height;
00219             y1 = x;
00220             x2 = _physical_width - y - 1;
00221             y2 = x + width - 1;
00222             break;
00223         case 2:
00224             x1= _physical_width - x - width;
00225             y1= _physical_height - y - height;
00226             x2= _physical_width - x - 1;
00227             y2= _physical_height - y - 1;
00228             break;
00229         case 3:
00230             x1 = y;
00231             y1 = _physical_height - x - width;
00232             x2 = y + height - 1;
00233             y2 = _physical_height - x - 1;
00234             break;
00235     }
00236     //Limit values
00237     if (x1 < 0) x1=0;
00238     if (x1 >= _physical_width) x1=_physical_width-1;
00239     if (x2 < 0) x2=0;
00240     if (x2 >= _physical_width) x2=_physical_width-1;
00241     if (y1 < 0) y1=0;
00242     if (y1 >= _physical_height) y1=_physical_height-1;
00243     if (y2 < 0) y2=0;
00244     if (y2 >= _physical_height) y2=_physical_height-1;
00245     
00246     
00247 /*    if ((width > 100) || (height > 100))
00248     {
00249         pc1.printf("x=%d\ty=%d\twidth=%d\theight=%d\tx1=%d\tx2=%d\ty1=%d\ty2=%d\n",x,y,width,height,x1,x2,y1,y2);
00250     }
00251 */    
00252     command(0x19);  // Y start
00253     data(y1);
00254     command(0x1A);  // Y end
00255     data(y2);
00256     command(0x17);  // X start
00257     data(x1);
00258     command(0x18);  // x end
00259     data(x2);
00260 
00261     switch (_rotation) {
00262         default:
00263         case 0:
00264             start_x=x1;
00265             start_y=y1;
00266             break;
00267         case 1:
00268             start_x=x1;
00269             start_y=y2;
00270             break;
00271         case 2:
00272             start_x=x2;
00273             start_y=y2;
00274             break;
00275         case 3:
00276             start_x=x2;
00277             start_y=y1;
00278             break;
00279     }
00280         
00281     command(0x20);  // memory accesspointer x
00282     data(start_x);
00283     command(0x21);  // memory accesspointer y
00284     data(start_y);
00285     
00286 }
00287 
00288 inline
00289 void OLEDSeps525f::_putp(int colour) {
00290     static int colour_prev=0xF000000, r=0, g=0, b=0;
00291 
00292     //Start "write data" command if not done already
00293     if ( ! _writing_pixels )
00294     {
00295         command(0x22);
00296     }
00297     //Only calculate rgb values if colour has changed
00298     if (colour_prev != colour)
00299     {
00300         r=(colour & 0xFF0000) >> 16;
00301         g=(colour & 0x00FF00) >> 8;
00302         b=colour & 0xFF;
00303         colour_prev=colour;
00304     }
00305 
00306     rgbdot(r,g,b);
00307 }
00308 
00309 void OLEDSeps525f::orientation(int o) {
00310         _rotation=o & 3;
00311         
00312         //Set write direction
00313         command(0x16);
00314         switch(_rotation) {
00315             case 0:
00316             default:
00317                 //HC=1, VC=1, HV=0
00318                 data(0x76);
00319                 _width=_physical_width;
00320                 _height=_physical_height;
00321                 break;
00322             case 1:
00323                 //HC=0, VC=1, HV=1
00324                 data(0x73);
00325                 _width=_physical_height;
00326                 _height=_physical_width;
00327                 break;
00328             case 2:
00329                 //HC=0, VC=0, HV=0
00330                 data(0x70);
00331                 _width=_physical_width;
00332                 _height=_physical_height;
00333                 break;
00334             case 3:
00335                 //HC=1, VC=0, HV=1
00336                 data(0x75);
00337                 _width=_physical_height;
00338                 _height=_physical_width;
00339                 break;
00340         }
00341         _columns = _width/8;
00342         _rows = _height/8;
00343 }
00344 
00345 
00346 const unsigned char FONT8x8[97][8] = {
00347     0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00, // columns, rows, num_bytes_per_char
00348     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // space 0x20
00349     0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00, // !
00350     0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00, // "
00351     0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00, // #
00352     0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00, // $
00353     0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00, // %
00354     0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00, // &
00355     0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00, // '
00356     0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00, // (
00357     0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00, // )
00358     0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00, // *
00359     0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00, // +
00360     0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, // ,
00361     0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // -
00362     0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, // .
00363     0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00, // / (forward slash)
00364     0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00, // 0 0x30
00365     0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00, // 1
00366     0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00, // 2
00367     0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00, // 3
00368     0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00, // 4
00369     0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00, // 5
00370     0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00, // 6
00371     0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00, // 7
00372     0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00, // 8
00373     0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00, // 9
00374     0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00, // :
00375     0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30, // ;
00376     0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00, // <
00377     0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, // =
00378     0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00, // >
00379     0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00, // ?
00380     0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00, // @ 0x40
00381     0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00, // A
00382     0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00, // B
00383     0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00, // C
00384     0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00, // D
00385     0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00, // E
00386     0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00, // F
00387     0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00, // G
00388     0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00, // H
00389     0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // I
00390     0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00, // J
00391     0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00, // K
00392     0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00, // L
00393     0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00, // M
00394     0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00, // N
00395     0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00, // O
00396     0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00, // P 0x50
00397     0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00, // Q
00398     0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00, // R
00399     0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00, // S
00400     0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00, // T
00401     0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00, // U
00402     0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00, // V
00403     0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00, // W
00404     0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00, // X
00405     0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00, // Y
00406     0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00, // Z
00407     0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00, // [
00408     0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00, // \ (back slash)
00409     0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00, // ]
00410     0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00, // ^
00411     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, // _
00412     0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00, // ` 0x60
00413     0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00, // a
00414     0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00, // b
00415     0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00, // c
00416     0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00, // d
00417     0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00, // e
00418     0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00, // f
00419     0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C, // g
00420     0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00, // h
00421     0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00, // i
00422     0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C, // j
00423     0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00, // k
00424     0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // l
00425     0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00, // m
00426     0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00, // n
00427     0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00, // o
00428     0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78, // p
00429     0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F, // q
00430     0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00, // r
00431     0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00, // s
00432     0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00, // t
00433     0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00, // u
00434     0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00, // v
00435     0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00, // w
00436     0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00, // x
00437     0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C, // y
00438     0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00, // z
00439     0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00, // {
00440     0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00, // |
00441     0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00, // }
00442     0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00, // ~
00443     0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00
00444 }; // DEL
00445 
00446 void OLEDSeps525f::locate(int column, int row) {
00447     _row = row;
00448     _column = column;
00449 }
00450 
00451 void OLEDSeps525f::newline() {
00452     _column = 0;
00453     _row++;
00454     if (_row >= _rows) {
00455         _row = 0;
00456     }
00457 }
00458 
00459 void OLEDSeps525f::tablength(int l) {
00460     _tablength = l;
00461 }
00462 
00463 int OLEDSeps525f::_putc(int value) {
00464     int x = _column * 8;  // FIXME: Char sizes
00465     int y = _row * 8;
00466     
00467     //Interpret some ASCII control codes
00468     if (value < 0x1F)
00469     {
00470         switch (value)
00471         {
00472             //Backspace
00473             case 0x08:
00474                 _column--;
00475                 if (_column < 0) {
00476                     _column = 0; 
00477                     _row--;
00478                     if (_row < 0) {
00479                         _row = _rows - 1;
00480                     }
00481                 }
00482                 break;
00483             //Tab
00484             case 0x09:
00485                 _column=((_column / _tablength) * _tablength) + _tablength;
00486                 if (_column > _columns) {
00487                     newline();
00488                 }
00489                 break;
00490             //Line feed
00491             case 0x0A:
00492                 newline();
00493                 break;
00494             //Vertical tab
00495             case 0x0B:
00496                 _row++;
00497                 if (_row >= _rows) {
00498                     _row = 0;
00499                 }
00500                 break;
00501             //Carriage return
00502             case 0x0D:
00503                 _column = 0;
00504                 break;
00505             //Default ignore
00506             default:
00507                 break;
00508         }
00509     } else
00510     {
00511         if (value < 128)
00512         {
00513             bitblit(x + 1, y + 1, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
00514 
00515             _column++;
00516         }
00517     }
00518     
00519     if (_column < 0) _column=0;
00520     if (_column >= _columns) {
00521         _row++;
00522         _column = 0;
00523     }
00524 
00525     if (_row < 0) _row=0;
00526     if (_row >= _rows) {
00527         _row = 0;
00528     }
00529 return value;
00530 }
00531 
00532 void OLEDSeps525f::cls() {
00533     fill(0, 0, _width, _height, _background);
00534     _row = 0;
00535     _column = 0;
00536 }
00537 
00538 int OLEDSeps525f::width() {
00539     return _width;
00540 }
00541 
00542 int OLEDSeps525f::height() {
00543     return _height;
00544 }
00545 
00546 int OLEDSeps525f::columns() {
00547     return _columns;
00548 }
00549 
00550 int OLEDSeps525f::rows() {
00551     return _rows;
00552 }
00553 
00554 int OLEDSeps525f::tablength() {
00555     return _tablength;
00556 }
00557 
00558 int OLEDSeps525f::orientation() {
00559    return(_rotation);
00560 } 
00561 
00562 int OLEDSeps525f::foreground() {
00563     return(_foreground);
00564 }
00565 
00566 int OLEDSeps525f::background() {
00567     return(_background);
00568 }
00569 
00570 void OLEDSeps525f::window(int x, int y, int width, int height) {
00571     _window(x, y, width, height);
00572 }
00573 
00574 void OLEDSeps525f::putp(int colour) {
00575     _putp(colour);
00576 }
00577 
00578 void OLEDSeps525f::pixel(int x, int y, int colour) {
00579     _window(x, y, 1, 1);
00580     _putp(colour);
00581 }
00582 
00583 void OLEDSeps525f::fill(int x, int y, int width, int height, int colour) {
00584     int r, g, b;
00585     
00586     _window(x, y, width, height);
00587     //Start "write data" command if not done already
00588     if ( ! _writing_pixels )
00589     {
00590         command(0x22);
00591     }
00592     r=(colour & 0xFF0000) >> 16;
00593     g=(colour & 0x00FF00) >> 8;
00594     b=colour & 0xFF;
00595     for (int i=0; i<width*height; i++) {
00596         rgbdot(r, g, b);
00597     }
00598     _window(0, 0, _width, _height);
00599 }
00600 
00601 
00602 void OLEDSeps525f::blit(int x, int y, int width, int height, const int* colour) {
00603     _window(x, y, width, height);
00604     for (int i=0; i<width*height; i++) {
00605         _putp(colour[i]);
00606     }
00607     _window(0, 0, _width, _height);
00608 }
00609 
00610 void OLEDSeps525f::foreground(int v) {
00611     _foreground = v;
00612 }
00613 
00614 void OLEDSeps525f::background(int v) {
00615     _background = v;
00616 }
00617 
00618 void OLEDSeps525f::bitblit(int x, int y, int width, int height, const char* bitstream) {
00619     _window(x, y, width, height);
00620     for (int i=0; i<height*width; i++) {
00621         int byte = i / 8;
00622         int bit = i % 8;
00623         int colour = ((bitstream[byte] << bit) & 0x80) ? _foreground : _background;
00624         _putp(colour);
00625     }
00626     _window(0, 0, _width, _height);
00627 }