Simon Blandford
/
OLEDSeps525f
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Fri Jul 15 2022 13:46:49 by 1.7.2