Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of SFE_MicroOLED by
SFE_MicroOLED.cpp
00001 /****************************************************************************** 00002 SFE_MicroOLED.cpp 00003 Main source code for the MicroOLED mbed Library 00004 Jim Lindblom @ SparkFun Electronics 00005 October 26, 2014 00006 https://github.com/sparkfun/Micro_OLED_Breakout/tree/master/Firmware/Arduino/libraries/SFE_MicroOLED 00007 Adapted for mbed by Nenad Milosevic 00008 March, 2015 00009 Adapted for 64x32 oled my Goran Mahovlić 00010 This file defines the hardware SPI interface for the Micro OLED Breakout. 00011 Development environment specifics: 00012 Various suitable mbed platforms 00013 Micro OLED Breakout v1.0 00014 This code was heavily based around the MicroView library, written by GeekAmmo 00015 (https://github.com/geekammo/MicroView-Arduino-Library), and released under 00016 the terms of the GNU General Public License as published by the Free Software 00017 Foundation, either version 3 of the License, or (at your option) any later 00018 version. 00019 This program is distributed in the hope that it will be useful, 00020 but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 GNU General Public License for more details. 00023 You should have received a copy of the GNU General Public License 00024 along with this program. If not, see <http://www.gnu.org/licenses/>. 00025 ******************************************************************************/ 00026 00027 #include "mbed.h" 00028 #include <stdarg.h> 00029 #include "SFE_MicroOLED.h" 00030 00031 // Add header of the fonts here. 00032 #include "font5x7.h" 00033 #include "font8x16.h" 00034 #include "fontlargenumber.h" 00035 #include "7segment.h" 00036 00037 // Change the total fonts included 00038 #define TOTALFONTS 4 00039 extern Serial pc; 00040 // Add the font name as declared in the header file. 00041 unsigned const char *MicroOLED::fontsPointer[]={ 00042 font5x7 00043 ,font8x16 00044 ,sevensegment 00045 ,fontlargenumber 00046 }; 00047 00048 /** \brief MicroOLED screen buffer. 00049 Page buffer LCDWIDTH x LCDHEIGHT divided by 8 00050 Page buffer is required because in SPI mode, the host cannot read the SSD1306's GDRAM of the controller. This page buffer serves as a scratch RAM for graphical functions. All drawing function will first be drawn on this page buffer, only upon calling display() function will transfer the page buffer to the actual LCD controller's memory. 00051 */ 00052 static uint8_t screenmemory [LCDWIDTH * LCDHEIGHT / 8]; 00053 /* SSD1306 Memory organised in 128 horizontal pixel and 8 rows of byte 00054 B B .............B ----- 00055 y y .............y \ 00056 t t .............t \ 00057 e e .............e \ 00058 0 1 .............127 \ 00059 \ 00060 D0 D0.............D0 \ 00061 D1 D1.............D1 / ROW 0 00062 D2 D2.............D2 / 00063 D3 D3.............D3 / 00064 D4 D4.............D4 / 00065 D5 D5.............D5 / 00066 D6 D6.............D6 / 00067 D7 D7.............D7 ---- 00068 */ 00069 00070 /** \brief Initialisation of MicroOLED Library. 00071 Setup IO pins and parameters for SPI then send initialisation commands to the SSD1306 controller inside the OLED. 00072 */ 00073 void MicroOLED::init(int spi_mode, int spi_freq) 00074 { 00075 //pc.printf("Trying to init OLED\n"); 00076 00077 // default 5x7 font 00078 setFontType(0); 00079 setColor(WHITE); 00080 setDrawMode(NORM); 00081 setCursor(0,0); 00082 //pc.printf("Set fonts and modes\n"); 00083 00084 memset(screenmemory,0,(LCDWIDTH * LCDHEIGHT / 8)); // initially clear Page buffer 00085 //pc.printf("Acc screen mem and init to 0\n"); 00086 00087 // Initialize the SPI library: 00088 dcPin = 0; 00089 csPin = 1; 00090 miol_spi.format(8, spi_mode); // 8 Bit wide SPI and Mode (0 - 3) 00091 miol_spi.frequency(spi_freq); // SPI speed in Hz 00092 //pc.printf("spi done\n"); 00093 // Display reset routine 00094 rstPin = 1; // Initially set RST HIGH 00095 wait_ms(5); // VDD (3.3V) goes high at start, lets just chill for 5 ms 00096 rstPin = 0; // Bring RST low, reset the display 00097 wait_ms(10); // wait 10ms 00098 rstPin = 1; // Set RST HIGH, bring out of reset 00099 wait_ms(5); // wait 5ms 00100 00101 //pc.printf("Reset done\n"); 00102 // Original Espruino commands 00103 // uint8_t initCmds[] = { 0xAe,0xD5,0x80,0xA8,31,0xD3,0x0,0x40,0x8D,0x14,0x20,0x00,0xA1,0xC8,0xDA,0x12,0x81,0xCF,0xD9,0xF1,0xDb,0x40,0xA4,0xA6,0xAf}; 00104 00105 // Latest Espruino commands 00106 uint8_t initCmds[] = { 0xAe,0xD5,0x80,0xA8,31,0xD3,0x0,0x40,0x8D,0x14,0x20,0x01,0xA1,0xC8,0xDA,0x12,0x81,0xCF,0xD9,0xF1,0xDb,0x40,0xA4,0xA6,0xAf }; 00107 00108 // Init commands from the OLED Display datasheet 00109 uint8_t initCmdsOLED_SPEC[] = { 0xAE, /*display off*/ 00110 0x00, /*set lower column address*/ 00111 0x12, /*set higher column address*/ 00112 0x00, /*set display start line*/ 00113 0xB0, /*set page address*/ 00114 0x81, /*contract control*/ 00115 0x4f, /*128*/ 00116 0xA1, /*set segment remap*/ 00117 0xA6, /*normal / reverse*/ 00118 0xA8, /*multiplex ratio*/ 00119 0x1F, /*duty = 1/32*/ 00120 0xC8, /*Com scan direction*/ 00121 0xD3, /*set display offset*/ 00122 0x00, 00123 0xD5, /*set osc division*/ 00124 0x80, 00125 0xD9, /*set pre-charge period*/ 00126 0x1f, 00127 0xDA, /*set COM pins*/ 00128 0x12, 00129 0xdb, /*set vcomh*/ 00130 0x40, 00131 0x8d, /*set charge pump enable*/ 00132 0x10, 00133 0xAF /*display ON*/ }; 00134 00135 //pc.printf("before command\n"); 00136 command (initCmdsOLED_SPEC,sizeof(initCmds)); 00137 /* 00138 miol_spi.write(0x21); 00139 miol_spi.write(0); 00140 miol_spi.write(127); 00141 miol_spi.write(0x22); 00142 miol_spi.write(0); 00143 miol_spi.write(7); 00144 00145 */ 00146 //pc.printf("command done 1\n"); 00147 command(MEMORYMODE, 0); 00148 clear(ALL); // Erase hardware memory inside the OLED controller to avoid random data in memory. 00149 // command(DISPLAYON); 00150 //pc.printf("finsihed all tasks of init\n"); 00151 } 00152 00153 /** \brief Send the display command byte(s) 00154 00155 Send command(s) via SPI to SSD1306 controller. 00156 */ 00157 void MicroOLED::command(uint8_t c) { 00158 00159 dcPin = 0; // DC pin LOW for a command 00160 csPin = 0; // SS LOW to initialize transfer 00161 miol_spi.write(c); // Transfer the command byte 00162 csPin = 1; // SS HIGH to end transfer 00163 00164 } 00165 00166 void MicroOLED::command(uint8_t c1, uint8_t c2) { 00167 00168 dcPin = 0; // DC pin LOW for a command 00169 csPin = 0; // SS LOW to initialize transfer 00170 miol_spi.write(c1); // Transfer the command byte 00171 miol_spi.write(c2); // Transfer the first parameter 00172 csPin = 1; // SS HIGH to end transfer 00173 00174 } 00175 00176 void MicroOLED::command(uint8_t c1, uint8_t c2, uint8_t c3) { 00177 00178 dcPin = 0; // DC pin LOW for a command 00179 csPin = 0; // SS LOW to initialize transfer 00180 miol_spi.write(c1); // Transfer the command byte 00181 miol_spi.write(c2); // Transfer the first parameter 00182 miol_spi.write(c3); // Transfer the second parameter 00183 csPin = 1; // SS HIGH to end transfer 00184 00185 } 00186 00187 void MicroOLED::command(uint8_t c1, uint8_t c2, uint8_t c3, uint8_t c4, uint8_t c5, uint8_t c6, uint8_t c7, uint8_t c8) { 00188 00189 dcPin = 0; // DC pin LOW for a command 00190 csPin = 0; // SS LOW to initialize transfer 00191 miol_spi.write(c1); // Transfer the command byte 00192 miol_spi.write(c2); // Transfer the first parameter 00193 miol_spi.write(c3); // Transfer the second parameter 00194 miol_spi.write(c4); // Transfer the third parameter 00195 miol_spi.write(c5); // Transfer the fourth parameter 00196 miol_spi.write(c6); // Transfer the fifth parameter 00197 miol_spi.write(c7); // Transfer the sixth parameter 00198 miol_spi.write(c8); // Transfer the seventh parameter 00199 csPin = 1; // SS HIGH to end transfer 00200 00201 } 00202 00203 void MicroOLED::command(uint8_t cmds[],int length) { 00204 00205 // pc.printf("inside command function \n"); 00206 dcPin = 0; // DC pin LOW for a command 00207 csPin = 0; // SS LOW to initialize transfer 00208 for(int i=0;i<length;i++) 00209 { 00210 //pc.printf("inside loop %d,%d \n",i,cmds[i]); 00211 00212 miol_spi.write(cmds[i]); 00213 } 00214 csPin = 1; // SS HIGH to end transfer 00215 00216 } 00217 00218 /** \brief Clear screen buffer or SSD1306's memory. 00219 00220 To clear all GDRAM inside the LCD controller, pass in the variable mode = ALL and to clear screen page buffer pass in the variable mode = PAGE. 00221 */ 00222 void MicroOLED::clear(uint8_t mode) { 00223 if (mode==ALL) 00224 { 00225 csPin = 0; 00226 dcPin = 0; 00227 00228 for (int b=0;b<4;b++) 00229 { 00230 dcPin = 0; 00231 miol_spi.write(0xb0+b); 00232 miol_spi.write(0x00); 00233 miol_spi.write(0x12); 00234 dcPin = 1; 00235 for (int i = 0; i < 64; i++) 00236 { 00237 miol_spi.write(0); 00238 } 00239 } 00240 csPin = 1; 00241 } 00242 else 00243 { 00244 memset(screenmemory,0,(LCDWIDTH * LCDPAGES)); 00245 //display(); 00246 } 00247 } 00248 00249 /** \brief Clear or replace screen buffer or SSD1306's memory with a character. 00250 00251 To clear GDRAM inside the LCD controller, pass in the variable mode = ALL with c character and to clear screen page buffer, pass in the variable mode = PAGE with c character. 00252 */ 00253 void MicroOLED::clear(uint8_t mode, uint8_t c) { 00254 if (mode==ALL) { 00255 csPin = 0; 00256 dcPin = 0; 00257 00258 for (int b=0;b<4;b++) 00259 { 00260 dcPin = 0; 00261 miol_spi.write(0xb0+b); 00262 miol_spi.write(0x00); 00263 miol_spi.write(0x12); 00264 dcPin = 1; 00265 for (int i = 0; i < 64; i++) 00266 { 00267 miol_spi.write(c); 00268 } 00269 } 00270 csPin = 1; 00271 00272 } 00273 else 00274 { 00275 memset(screenmemory,c,LCDWIDTH * LCDPAGES); 00276 display(); 00277 } 00278 } 00279 00280 /** \brief Invert display. 00281 00282 The WHITE color of the display will turn to BLACK and the BLACK will turn to WHITE. 00283 */ 00284 void MicroOLED::invert(boolean inv) { 00285 if (inv) 00286 command(INVERTDISPLAY); 00287 else 00288 command(NORMALDISPLAY); 00289 } 00290 00291 /** \brief Set contrast. 00292 00293 OLED contract value from 0 to 255. Note: Contrast level is not very obvious. 00294 */ 00295 void MicroOLED::contrast(uint8_t contrast) { 00296 command(SETCONTRAST, contrast); // 0x81 00297 } 00298 00299 /** \brief Transfer display memory. 00300 00301 Bulk move the screen buffer to the SSD1306 controller's memory so that images/graphics drawn on the screen buffer will be displayed on the OLED. 00302 */ 00303 void MicroOLED::display(void) { 00304 00305 csPin = 0; 00306 dcPin = 0; 00307 00308 00309 00310 for (int b=0;b<4;b++) 00311 { 00312 dcPin = 0; 00313 miol_spi.write(0xb0+b); 00314 miol_spi.write(0x00); 00315 miol_spi.write(0x12); 00316 dcPin = 1; 00317 for (int i = 0; i < 64; i++) 00318 { 00319 miol_spi.write(screenmemory[i+64*b]); 00320 } 00321 } 00322 csPin = 1; 00323 } 00324 00325 /* 00326 Classic text print functions. 00327 */ 00328 00329 void MicroOLED::putc(char c) { 00330 if (c == '\n') { 00331 cursorY += fontHeight; 00332 cursorX = 0; 00333 } else if (c == '\r') { 00334 // skip 00335 } else { 00336 drawChar(cursorX, cursorY, (uint8_t)c, foreColor, drawMode); 00337 cursorX += fontWidth+1; 00338 if ((cursorX > (LCDWIDTH - fontWidth))) { 00339 cursorY += fontHeight; 00340 cursorX = 0; 00341 } 00342 } 00343 } 00344 00345 void MicroOLED::puts(const char *cstring) { 00346 while (*cstring != 0) { 00347 putc(*cstring++); 00348 } 00349 } 00350 00351 void MicroOLED::printf(const char *format, ...) 00352 { 00353 static char buffer[128]; 00354 00355 va_list args; 00356 va_start(args, format); 00357 vsprintf(buffer, format, args); 00358 va_end(args); 00359 00360 char *c = (char *)&buffer; 00361 while (*c != 0) 00362 { 00363 putc(*c++); 00364 } 00365 } 00366 00367 /** \brief Set cursor position. 00368 00369 MicroOLED's cursor position to x,y. 00370 */ 00371 void MicroOLED::setCursor(uint8_t x, uint8_t y) { 00372 cursorX=x; 00373 cursorY=y; 00374 } 00375 00376 /** \brief Draw pixel. 00377 00378 Draw pixel using the current fore color and current draw mode in the screen buffer's x,y position. 00379 */ 00380 void MicroOLED::pixel(uint8_t x, uint8_t y) { 00381 pixel(x,y,foreColor,drawMode); 00382 } 00383 00384 /** \brief Draw pixel with color and mode. 00385 00386 Draw color pixel in the screen buffer's x,y position with NORM or XOR draw mode. 00387 */ 00388 void MicroOLED::pixel(uint8_t x, uint8_t y, uint8_t color, uint8_t mode) { 00389 if ((x>=LCDWIDTH) || (y>=LCDHEIGHT)) 00390 return; 00391 00392 if (mode==XOR) { 00393 if (color==WHITE) 00394 screenmemory[x+ (y/8)*LCDWIDTH] ^= _BV((y%8)); 00395 } 00396 else { 00397 if (color==WHITE) 00398 screenmemory[x+ (y/8)*LCDWIDTH] |= _BV((y%8)); 00399 else 00400 screenmemory[x+ (y/8)*LCDWIDTH] &= ~_BV((y%8)); 00401 } 00402 } 00403 00404 /** \brief Draw line. 00405 00406 Draw line using current fore color and current draw mode from x0,y0 to x1,y1 of the screen buffer. 00407 */ 00408 void MicroOLED::line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) { 00409 line(x0,y0,x1,y1,foreColor,drawMode); 00410 } 00411 00412 /** \brief Draw line with color and mode. 00413 00414 Draw line using color and mode from x0,y0 to x1,y1 of the screen buffer. 00415 */ 00416 void MicroOLED::line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t color, uint8_t mode) { 00417 uint8_t steep = abs(y1 - y0) > abs(x1 - x0); 00418 if (steep) { 00419 swap(x0, y0); 00420 swap(x1, y1); 00421 } 00422 00423 if (x0 > x1) { 00424 swap(x0, x1); 00425 swap(y0, y1); 00426 } 00427 00428 uint8_t dx, dy; 00429 dx = x1 - x0; 00430 dy = abs(y1 - y0); 00431 00432 int8_t err = dx / 2; 00433 int8_t ystep; 00434 00435 if (y0 < y1) { 00436 ystep = 1; 00437 } else { 00438 ystep = -1;} 00439 00440 for (; x0<x1; x0++) { 00441 if (steep) { 00442 pixel(y0, x0, color, mode); 00443 } else { 00444 pixel(x0, y0, color, mode); 00445 } 00446 err -= dy; 00447 if (err < 0) { 00448 y0 += ystep; 00449 err += dx; 00450 } 00451 } 00452 } 00453 00454 /** \brief Draw horizontal line. 00455 00456 Draw horizontal line using current fore color and current draw mode from x,y to x+width,y of the screen buffer. 00457 */ 00458 void MicroOLED::lineH(uint8_t x, uint8_t y, uint8_t width) { 00459 line(x,y,x+width,y,foreColor,drawMode); 00460 } 00461 00462 /** \brief Draw horizontal line with color and mode. 00463 00464 Draw horizontal line using color and mode from x,y to x+width,y of the screen buffer. 00465 */ 00466 void MicroOLED::lineH(uint8_t x, uint8_t y, uint8_t width, uint8_t color, uint8_t mode) { 00467 line(x,y,x+width,y,color,mode); 00468 } 00469 00470 /** \brief Draw vertical line. 00471 00472 Draw vertical line using current fore color and current draw mode from x,y to x,y+height of the screen buffer. 00473 */ 00474 void MicroOLED::lineV(uint8_t x, uint8_t y, uint8_t height) { 00475 line(x,y,x,y+height,foreColor,drawMode); 00476 } 00477 00478 /** \brief Draw vertical line with color and mode. 00479 00480 Draw vertical line using color and mode from x,y to x,y+height of the screen buffer. 00481 */ 00482 void MicroOLED::lineV(uint8_t x, uint8_t y, uint8_t height, uint8_t color, uint8_t mode) { 00483 line(x,y,x,y+height,color,mode); 00484 } 00485 00486 /** \brief Draw rectangle. 00487 00488 Draw rectangle using current fore color and current draw mode from x,y to x+width,y+height of the screen buffer. 00489 */ 00490 void MicroOLED::rect(uint8_t x, uint8_t y, uint8_t width, uint8_t height) { 00491 rect(x,y,width,height,foreColor,drawMode); 00492 } 00493 00494 /** \brief Draw rectangle with color and mode. 00495 00496 Draw rectangle using color and mode from x,y to x+width,y+height of the screen buffer. 00497 */ 00498 void MicroOLED::rect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color , uint8_t mode) { 00499 uint8_t tempHeight; 00500 00501 lineH(x,y, width, color, mode); 00502 lineH(x,y+height-1, width, color, mode); 00503 00504 tempHeight=height-2; 00505 00506 // skip drawing vertical lines to avoid overlapping of pixel that will 00507 // affect XOR plot if no pixel in between horizontal lines 00508 if (tempHeight<1) return; 00509 00510 lineV(x,y+1, tempHeight, color, mode); 00511 lineV(x+width-1, y+1, tempHeight, color, mode); 00512 } 00513 00514 /** \brief Draw filled rectangle. 00515 00516 Draw filled rectangle using current fore color and current draw mode from x,y to x+width,y+height of the screen buffer. 00517 */ 00518 void MicroOLED::rectFill(uint8_t x, uint8_t y, uint8_t width, uint8_t height) { 00519 rectFill(x,y,width,height,foreColor,drawMode); 00520 } 00521 00522 /** \brief Draw filled rectangle with color and mode. 00523 00524 Draw filled rectangle using color and mode from x,y to x+width,y+height of the screen buffer. 00525 */ 00526 void MicroOLED::rectFill(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color , uint8_t mode) { 00527 // TODO - need to optimise the memory map draw so that this function will not call pixel one by one 00528 for (int i=x; i<x+width;i++) { 00529 lineV(i,y, height, color, mode); 00530 } 00531 } 00532 00533 /** \brief Draw circle. 00534 00535 Draw circle with radius using current fore color and current draw mode at x,y of the screen buffer. 00536 */ 00537 void MicroOLED::circle(uint8_t x0, uint8_t y0, uint8_t radius) { 00538 circle(x0,y0,radius,foreColor,drawMode); 00539 } 00540 00541 /** \brief Draw circle with color and mode. 00542 00543 Draw circle with radius using color and mode at x,y of the screen buffer. 00544 */ 00545 void MicroOLED::circle(uint8_t x0, uint8_t y0, uint8_t radius, uint8_t color, uint8_t mode) { 00546 //TODO - find a way to check for no overlapping of pixels so that XOR draw mode will work perfectly 00547 int8_t f = 1 - radius; 00548 int8_t ddF_x = 1; 00549 int8_t ddF_y = -2 * radius; 00550 int8_t x = 0; 00551 int8_t y = radius; 00552 00553 pixel(x0, y0+radius, color, mode); 00554 pixel(x0, y0-radius, color, mode); 00555 pixel(x0+radius, y0, color, mode); 00556 pixel(x0-radius, y0, color, mode); 00557 00558 while (x<y) { 00559 if (f >= 0) { 00560 y--; 00561 ddF_y += 2; 00562 f += ddF_y; 00563 } 00564 x++; 00565 ddF_x += 2; 00566 f += ddF_x; 00567 00568 pixel(x0 + x, y0 + y, color, mode); 00569 pixel(x0 - x, y0 + y, color, mode); 00570 pixel(x0 + x, y0 - y, color, mode); 00571 pixel(x0 - x, y0 - y, color, mode); 00572 00573 pixel(x0 + y, y0 + x, color, mode); 00574 pixel(x0 - y, y0 + x, color, mode); 00575 pixel(x0 + y, y0 - x, color, mode); 00576 pixel(x0 - y, y0 - x, color, mode); 00577 00578 } 00579 } 00580 00581 /** \brief Draw filled circle. 00582 00583 Draw filled circle with radius using current fore color and current draw mode at x,y of the screen buffer. 00584 */ 00585 void MicroOLED::circleFill(uint8_t x0, uint8_t y0, uint8_t radius) { 00586 circleFill(x0,y0,radius,foreColor,drawMode); 00587 } 00588 00589 /** \brief Draw filled circle with color and mode. 00590 00591 Draw filled circle with radius using color and mode at x,y of the screen buffer. 00592 */ 00593 void MicroOLED::circleFill(uint8_t x0, uint8_t y0, uint8_t radius, uint8_t color, uint8_t mode) { 00594 // TODO - - find a way to check for no overlapping of pixels so that XOR draw mode will work perfectly 00595 int8_t f = 1 - radius; 00596 int8_t ddF_x = 1; 00597 int8_t ddF_y = -2 * radius; 00598 int8_t x = 0; 00599 int8_t y = radius; 00600 00601 // Temporary disable fill circle for XOR mode. 00602 if (mode==XOR) return; 00603 00604 for (uint8_t i=y0-radius; i<=y0+radius; i++) { 00605 pixel(x0, i, color, mode); 00606 } 00607 00608 while (x<y) { 00609 if (f >= 0) { 00610 y--; 00611 ddF_y += 2; 00612 f += ddF_y; 00613 } 00614 x++; 00615 ddF_x += 2; 00616 f += ddF_x; 00617 00618 for (uint8_t i=y0-y; i<=y0+y; i++) { 00619 pixel(x0+x, i, color, mode); 00620 pixel(x0-x, i, color, mode); 00621 } 00622 for (uint8_t i=y0-x; i<=y0+x; i++) { 00623 pixel(x0+y, i, color, mode); 00624 pixel(x0-y, i, color, mode); 00625 } 00626 } 00627 } 00628 00629 /** \brief Get LCD height. 00630 00631 The height of the LCD return as byte. 00632 */ 00633 uint8_t MicroOLED::getLCDHeight(void) { 00634 return LCDHEIGHT; 00635 } 00636 00637 /** \brief Get LCD width. 00638 00639 The width of the LCD return as byte. 00640 */ 00641 uint8_t MicroOLED::getLCDWidth(void) { 00642 return LCDWIDTH; 00643 } 00644 00645 /** \brief Get font width. 00646 00647 The cucrrent font's width return as byte. 00648 */ 00649 uint8_t MicroOLED::getFontWidth(void) { 00650 return fontWidth; 00651 } 00652 00653 /** \brief Get font height. 00654 00655 The current font's height return as byte. 00656 */ 00657 uint8_t MicroOLED::getFontHeight(void) { 00658 return fontHeight; 00659 } 00660 00661 /** \brief Get font starting character. 00662 00663 Return the starting ASCII character of the currnet font, not all fonts start with ASCII character 0. Custom fonts can start from any ASCII character. 00664 */ 00665 uint8_t MicroOLED::getFontStartChar(void) { 00666 return fontStartChar; 00667 } 00668 00669 /** \brief Get font total characters. 00670 00671 Return the total characters of the current font. 00672 */ 00673 uint8_t MicroOLED::getFontTotalChar(void) { 00674 return fontTotalChar; 00675 } 00676 00677 /** \brief Get total fonts. 00678 00679 Return the total number of fonts loaded into the MicroOLED's flash memory. 00680 */ 00681 uint8_t MicroOLED::getTotalFonts(void) { 00682 return TOTALFONTS; 00683 } 00684 00685 /** \brief Get font type. 00686 00687 Return the font type number of the current font. 00688 */ 00689 uint8_t MicroOLED::getFontType(void) { 00690 return fontType; 00691 } 00692 00693 /** \brief Set font type. 00694 00695 Set the current font type number, ie changing to different fonts base on the type provided. 00696 */ 00697 uint8_t MicroOLED::setFontType(uint8_t type) { 00698 if (type>=TOTALFONTS) 00699 return false; 00700 00701 fontType = type; 00702 fontWidth = *(fontsPointer[fontType]+0); 00703 fontHeight = *(fontsPointer[fontType]+1); 00704 fontStartChar = *(fontsPointer[fontType]+2); 00705 fontTotalChar = *(fontsPointer[fontType]+3); 00706 fontMapWidth = (*(fontsPointer[fontType]+4) * 100) + *(fontsPointer[fontType]+5); // two bytes values into integer 16 00707 return true; 00708 } 00709 00710 /** \brief Set color. 00711 00712 Set the current draw's color. Only WHITE and BLACK available. 00713 */ 00714 void MicroOLED::setColor(uint8_t color) { 00715 foreColor=color; 00716 } 00717 00718 /** \brief Set draw mode. 00719 00720 Set current draw mode with NORM or XOR. 00721 */ 00722 void MicroOLED::setDrawMode(uint8_t mode) { 00723 drawMode=mode; 00724 } 00725 00726 /** \brief Draw character. 00727 00728 Draw character c using current color and current draw mode at x,y. 00729 */ 00730 void MicroOLED::drawChar(uint8_t x, uint8_t y, uint8_t c) { 00731 drawChar(x,y,c,foreColor,drawMode); 00732 } 00733 00734 /** \brief Draw character with color and mode. 00735 00736 Draw character c using color and draw mode at x,y. 00737 */ 00738 void MicroOLED::drawChar(uint8_t x, uint8_t y, uint8_t c, uint8_t color, uint8_t mode) { 00739 // TODO - New routine to take font of any height, at the moment limited to font height in multiple of 8 pixels 00740 00741 uint8_t rowsToDraw,row, tempC; 00742 uint8_t i,j,temp; 00743 uint16_t charPerBitmapRow,charColPositionOnBitmap,charRowPositionOnBitmap,charBitmapStartPosition; 00744 00745 if ((c<fontStartChar) || (c>(fontStartChar+fontTotalChar-1))) // no bitmap for the required c 00746 return; 00747 00748 tempC=c-fontStartChar; 00749 00750 // each row (in datasheet is call page) is 8 bits high, 16 bit high character will have 2 rows to be drawn 00751 rowsToDraw=fontHeight/8; // 8 is LCD's page size, see SSD1306 datasheet 00752 if (rowsToDraw<=1) rowsToDraw=1; 00753 00754 // the following draw function can draw anywhere on the screen, but SLOW pixel by pixel draw 00755 if (rowsToDraw==1) { 00756 for (i=0;i<fontWidth+1;i++) { 00757 if (i==fontWidth) // this is done in a weird way because for 5x7 font, there is no margin, this code add a margin after col 5 00758 temp=0; 00759 else 00760 temp = *(fontsPointer[fontType]+FONTHEADERSIZE+(tempC*fontWidth)+i); 00761 00762 for (j=0;j<8;j++) { // 8 is the LCD's page height (see datasheet for explanation) 00763 if (temp & 0x1) { 00764 pixel(x+i, y+j, color,mode); 00765 } 00766 else { 00767 pixel(x+i, y+j, !color,mode); 00768 } 00769 00770 temp >>=1; 00771 } 00772 } 00773 return; 00774 } 00775 00776 // font height over 8 bit 00777 // take character "0" ASCII 48 as example 00778 charPerBitmapRow=fontMapWidth/fontWidth; // 256/8 =32 char per row 00779 charColPositionOnBitmap=tempC % charPerBitmapRow; // =16 00780 charRowPositionOnBitmap=int(tempC/charPerBitmapRow); // =1 00781 charBitmapStartPosition=(charRowPositionOnBitmap * fontMapWidth * (fontHeight/8)) + (charColPositionOnBitmap * fontWidth) ; 00782 00783 // each row on LCD is 8 bit height (see datasheet for explanation) 00784 for(row=0;row<rowsToDraw;row++) { 00785 for (i=0; i<fontWidth;i++) { 00786 temp = *(fontsPointer[fontType]+FONTHEADERSIZE+(charBitmapStartPosition+i+(row*fontMapWidth))); 00787 for (j=0;j<8;j++) { // 8 is the LCD's page height (see datasheet for explanation) 00788 if (temp & 0x1) { 00789 pixel(x+i,y+j+(row*8), color, mode); 00790 } 00791 else { 00792 pixel(x+i,y+j+(row*8), !color, mode); 00793 } 00794 temp >>=1; 00795 } 00796 } 00797 } 00798 00799 } 00800 00801 /** \brief Stop scrolling. 00802 00803 Stop the scrolling of graphics on the OLED. 00804 */ 00805 void MicroOLED::scrollStop(void){ 00806 command(DEACTIVATESCROLL); 00807 } 00808 00809 /** \brief Right scrolling. 00810 00811 Set row start to row stop on the OLED to scroll right. Refer to http://learn.microview.io/intro/general-overview-of-microview.html for explanation of the rows. 00812 */ 00813 void MicroOLED::scrollRight(uint8_t start, uint8_t stop){ 00814 if (stop<start) // stop must be larger or equal to start 00815 return; 00816 scrollStop(); // need to disable scrolling before starting to avoid memory corrupt 00817 command(RIGHTHORIZONTALSCROLL, 0x00, start, 0x07, stop, 0x00, 0xFF, ACTIVATESCROLL); // scroll speed frames , TODO 00818 } 00819 00820 /** \brief Left scrolling. 00821 Set row start to row stop on the OLED to scroll left. Refer to http://learn.microview.io/intro/general-overview-of-microview.html for explanation of the rows. 00822 */ 00823 void MicroOLED::scrollLeft(uint8_t start, uint8_t stop){ 00824 if (stop<start) // stop must be larger or equal to start 00825 return; 00826 scrollStop(); // need to disable scrolling before starting to avoid memory corrupt 00827 command(LEFTHORIZONTALSCROLL, 0x00, start, 0x07, stop, 0x00, 0xFF, ACTIVATESCROLL); // scroll speed frames , TODO 00828 } 00829 00830 /** \brief Vertical flip. 00831 00832 Flip the graphics on the OLED vertically. 00833 */ 00834 void MicroOLED::flipVertical(boolean flip) { 00835 if (flip) { 00836 command(COMSCANINC); 00837 } 00838 else { 00839 command(COMSCANDEC); 00840 } 00841 } 00842 00843 /** \brief Horizontal flip. 00844 00845 Flip the graphics on the OLED horizontally. 00846 */ 00847 void MicroOLED::flipHorizontal(boolean flip) { 00848 if (flip) { 00849 command(SEGREMAP | 0x0); 00850 } 00851 else { 00852 command(SEGREMAP | 0x1); 00853 } 00854 } 00855 00856 /* 00857 Return a pointer to the start of the RAM screen buffer for direct access. 00858 */ 00859 uint8_t *MicroOLED::getScreenBuffer(void) { 00860 return screenmemory; 00861 } 00862 00863 /* 00864 Draw Bitmap image on screen. The array for the bitmap can be stored in main program file, so user don't have to mess with the library files. 00865 To use, create const uint8_t array that is LCDWIDTH x LCDHEIGHT pixels (LCDWIDTH * LCDHEIGHT / 8 bytes). Then call .drawBitmap and pass it the array. 00866 */ 00867 void MicroOLED::drawBitmap(const uint8_t * bitArray) 00868 { 00869 for (int i=0; i<(LCDWIDTH * LCDHEIGHT / 8); i++) 00870 screenmemory[i] = bitArray[i]; 00871 } 00872 00873 /** \brief Set SSD1306 page address. 00874 Send page address command and address to the SSD1306 OLED controller. 00875 */ 00876 void MicroOLED::setPageAddress(uint8_t add) { 00877 command(SETPAGE|add); 00878 return; 00879 } 00880 00881 /** \brief Set SSD1306 column address. 00882 Send column address command and address to the SSD1306 OLED controller. 00883 */ 00884 void MicroOLED::setColumnAddress(uint8_t add) { 00885 command((SETHIGHCOLUMN|(add>>4))+0x02, SETLOWCOLUMN|(0x0f&add)); 00886 return; 00887 }
Generated on Sun Jul 17 2022 15:06:09 by
1.7.2
