This library provides an OLED (SSD1332, 96x64xRGB) interface that best utilizes SSD1332's graphic accelerator (especially for drawing lines and rectangles). Though it still has some limitations --- it does not support 'clipping', odd numbers for circle/ellipse diameter, and so on, it runs quite fast. Enjoy the speed.
Fork of OLEDaccel by
OLEDaccel.cpp
00001 // 00002 // OLEDaccel: 96x64 OLED driver 00003 // (version 0.2, August 17, 2012) 00004 // xkozima@myu.ac.jp 00005 00006 #include "OLEDaccel.h" 00007 #include "font6x8.h" 00008 00009 OLED::OLED (PinName rstPin, PinName csPin, PinName dcPin, PinName mosiPin, PinName sckPin) : 00010 rst(rstPin), cs(csPin), dc(dcPin), spi(mosiPin, NC, sckPin) 00011 { 00012 // setup spi (8bit master @48MHz) 00013 spi.format(8,3); 00014 spi.frequency(48000000); 00015 wait_ms(20); 00016 00017 // reset OLED 00018 rst = 0; 00019 wait_ms(20); 00020 rst = 1; 00021 wait_ms(20); 00022 00023 // init command 00024 unsigned char cmd1[] = {0xa0, 0x70}; 00025 cmdOut(cmd1, 2); 00026 unsigned char cmd2[] = {0xaf}; 00027 cmdOut(cmd2, 1); 00028 unsigned char cmd3[] = {0x26, 0x01}; 00029 cmdOut(cmd3, 2); 00030 00031 // clear flags 00032 reversal = false; 00033 filling = true; 00034 00035 // clear and display on 00036 rect(0, 0, 96, 64, 0, 1); 00037 wait(0.1); 00038 cmdOutOne(0xaf); // display on 00039 } 00040 00041 void OLED::cmdOutOne(unsigned char cmdOne) 00042 { 00043 dc = 0; 00044 cs = 0; 00045 spi.write(cmdOne); 00046 cs = 1; 00047 } 00048 00049 void OLED::cmdOut(unsigned char *cmd, int length) 00050 { 00051 dc = 0; 00052 cs = 0; 00053 for (int i = 0; i < length; i++) { 00054 spi.write(*cmd++); 00055 } 00056 cs = 1; 00057 } 00058 00059 void OLED::dataOut(unsigned short *data, int length) 00060 { 00061 dc = 1; 00062 cs = 0; 00063 for (int i = 0; i < length; i++) { 00064 unsigned short d16 = *data++; 00065 spi.write((unsigned char) ((d16 & 0xff00) >> 8)); 00066 spi.write((unsigned char) (d16 & 0x00ff)); 00067 } 00068 cs = 1; 00069 } 00070 00071 unsigned short OLED::color (int r, int g, int b) 00072 { 00073 return ((b & 0xf8) << 8) | ((g & 0xfc) << 3) | ((r & 0xf8) >> 3); 00074 } 00075 00076 void OLED::clear (unsigned short color) 00077 { 00078 rect(0, 0, 96, 64, color, 1); 00079 } 00080 00081 void OLED::point(int x, int y, unsigned short color) 00082 { 00083 // draw a point (a small rectangle/filled) 00084 unsigned char c1 = (color & 0xf800) >> 10, 00085 c2 = (color & 0x07e0) >> 5, 00086 c3 = (color & 0x001f) << 1; 00087 unsigned char cmd[] = {0x22, x, y, x, y, 00088 c1, c2, c3, c1, c2, c3 }; 00089 cmdOut(cmd, 11); 00090 } 00091 00092 void OLED::rect (int x, int y, int w, int h, 00093 unsigned short color, int fill ) 00094 { 00095 unsigned char c1 = (color & 0xf800) >> 10, 00096 c2 = (color & 0x07e0) >> 5, 00097 c3 = (color & 0x001f) << 1; 00098 // 00099 // fill or no fill 00100 if (fill) { 00101 if (! filling) { 00102 unsigned char cmdF[] = {0x26, 1}; 00103 cmdOut(cmdF, 2); 00104 filling = true; 00105 } 00106 } 00107 else { 00108 if (filling) { 00109 unsigned char cmdN[] = {0x26, 0}; 00110 cmdOut(cmdN, 2); 00111 filling = false; 00112 } 00113 } 00114 // un-reverse 00115 if (reversal) { 00116 unsigned char cmdN[] = {0xa0, 0x70}; 00117 cmdOut(cmdN, 2); 00118 reversal = false; 00119 } 00120 // draw/fill the rectangle 00121 unsigned char cmd[] = {0x22, x, y, x + w - 1, y + h - 1, 00122 c1, c2, c3, c1, c2, c3 }; 00123 cmdOut(cmd, 11); 00124 // wait 00125 wait_us(w * h / 10); 00126 } 00127 00128 void OLED::line(int x1, int y1, int x2, int y2, unsigned short color) 00129 { 00130 unsigned char c1 = (color & 0xf800) >> 10, 00131 c2 = (color & 0x07e0) >> 5, 00132 c3 = (color & 0x001f) << 1; 00133 if (x1 < x2) { 00134 if (y1 < y2) { 00135 // normal 00136 unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3}; 00137 if (reversal) { 00138 unsigned char cmdN[] = {0xa0, 0x70}; 00139 cmdOut(cmdN, 2); 00140 reversal = false; 00141 } 00142 cmdOut(cmd, 8); 00143 } 00144 else if (y1 > y2) { 00145 // reversal 00146 if (! reversal) { 00147 unsigned char cmdR[] = {0xa0, 0x72}; 00148 cmdOut(cmdR, 2); 00149 reversal = true; 00150 } 00151 unsigned char cmd[] = {0x21, 95 - x2, y2, 95 - x1, y1, c1, c2, c3}; 00152 cmdOut(cmd, 8); 00153 } 00154 else { // y1 == y2 00155 // normal 00156 unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3}; 00157 if (reversal) { 00158 unsigned char cmdN[] = {0xa0, 0x70}; 00159 cmdOut(cmdN, 2); 00160 reversal = false; 00161 } 00162 cmdOut(cmd, 8); 00163 } 00164 } 00165 else if (x1 > x2) { 00166 if (y1 < y2) { 00167 // reversal 00168 if (! reversal) { 00169 unsigned char cmdR[] = {0xa0, 0x72}; 00170 cmdOut(cmdR, 2); 00171 reversal = true; 00172 } 00173 unsigned char cmd[] = {0x21, 95 - x2, y2, 95 - x1, y1, c1, c2, c3}; 00174 cmdOut(cmd, 8); 00175 } 00176 else if (y1 > y2) { 00177 // normal 00178 unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3}; 00179 if (reversal) { 00180 unsigned char cmdN[] = {0xa0, 0x70}; 00181 cmdOut(cmdN, 2); 00182 reversal = false; 00183 } 00184 cmdOut(cmd, 8); 00185 } 00186 else { // y1 == y2 00187 // reversal 00188 unsigned char cmd[] = {0xa0, 0x72, 00189 0x21, 95 - x2, y2, 95 - x1, y1, c1, c2, c3, 00190 0xa0, 0x70 }; 00191 cmdOut(cmd, 12); 00192 } 00193 } 00194 else { // x1 == x2 00195 if (y1 < y2) { 00196 // normal 00197 unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3}; 00198 if (reversal) { 00199 unsigned char cmdN[] = {0xa0, 0x70}; 00200 cmdOut(cmdN, 2); 00201 reversal = false; 00202 } 00203 cmdOut(cmd, 8); 00204 } 00205 else if (y1 > y2) { 00206 // normal (force downward) 00207 unsigned char cmd[] = {0x21, x2, y2, x1, y1, c1, c2, c3}; 00208 cmdOut(cmd, 8); 00209 } 00210 else { // y1 == y2 00211 // normal (point) 00212 unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3}; 00213 if (reversal) { 00214 unsigned char cmdN[] = {0xa0, 0x70}; 00215 cmdOut(cmdN, 2); 00216 reversal = false; 00217 } 00218 cmdOut(cmd, 8); 00219 } 00220 } 00221 // wait 00222 wait_us(1); 00223 } 00224 00225 void OLED::circle(int x, int y, int r, unsigned short color, int fill) 00226 { 00227 // exception 00228 if (r < 1) { 00229 line(x, y, x, y, color); 00230 return; 00231 } else if (r == 1) { 00232 rect(x - 1, y - 1, 3, 3, color, fill); 00233 return; 00234 } 00235 // ok, go 00236 int xx = 0, 00237 yy = r, 00238 err = 2 - 2 * r; 00239 // iteration 00240 do { 00241 // draw it! 00242 if (fill) { 00243 line(x + xx, y + yy, x + xx, y, color); 00244 line(x - xx, y + yy, x, y + yy, color); 00245 line(x - xx, y - yy, x - xx, y, color); 00246 line(x + xx, y - yy, x, y - yy, color); 00247 } 00248 else { 00249 point(x + xx, y + yy, color); 00250 point(x - xx, y + yy, color); 00251 point(x - xx, y - yy, color); 00252 point(x + xx, y - yy, color); 00253 } 00254 // walk 00255 if (err > -yy) { 00256 yy--; 00257 err += 1 - 2 * yy; 00258 } 00259 if (err <= xx) { 00260 xx++; 00261 err += 1 + 2 * xx; 00262 } 00263 } while (yy >= 0); 00264 } 00265 00266 void OLED::ellipse(int x, int y, int rx, int ry, unsigned short color, int fill) 00267 { 00268 // exception 00269 if (rx < 1) { 00270 line(x, y - ry, x, y + ry, color); 00271 return; 00272 } 00273 else if (ry < 1) { 00274 line(x - rx, y, x + rx, y, color); 00275 return; 00276 } 00277 // ok, go 00278 int xx = -rx, yy = 0; 00279 int e2 = ry, 00280 dx = (2 * xx + 1) * e2 * e2, 00281 dy = xx * xx, 00282 err = dx + dy; 00283 do { 00284 if (fill) { 00285 line(x + xx, y + yy, x + xx, y, color); 00286 line(x - xx, y + yy, x, y + yy, color); 00287 line(x - xx, y - yy, x - xx, y, color); 00288 line(x + xx, y - yy, x, y - yy, color); 00289 } 00290 else { 00291 point(x + xx, y + yy, color); 00292 point(x - xx, y + yy, color); 00293 point(x - xx, y - yy, color); 00294 point(x + xx, y - yy, color); 00295 } 00296 e2 = 2 * err; 00297 if (e2 >= dx) { 00298 xx++; 00299 dx += 2 * ry * ry; 00300 err += dx; 00301 } 00302 if (e2 <= dy) { 00303 yy++; 00304 dy += 2 * rx * rx; 00305 err += dy; 00306 } 00307 } while (xx <= 0); 00308 if (fill) { 00309 while (yy++ < ry) { 00310 line(x, y + yy, x, y, color); 00311 line(x, y - yy, x, y, color); 00312 } 00313 } 00314 else { 00315 while (yy++ < ry) { 00316 point(x, y + yy, color); 00317 point(x, y - yy, color); 00318 } 00319 } 00320 } 00321 00322 void OLED::image(int x, int y, int w, int h, unsigned short *image16) 00323 { 00324 // un-reverse 00325 if (reversal) { 00326 unsigned char cmdN[] = {0xa0, 0x70}; 00327 cmdOut(cmdN, 2); 00328 reversal = false; 00329 } 00330 // setup the region to fill 00331 unsigned char cmd[]={0x15, x, x+w-1, 0x75, y, y+h-1}; 00332 cmdOut(cmd, 6); 00333 // fill up the region with the image data 00334 dataOut(image16, w * h); 00335 // wait 00336 wait_us(100); 00337 } 00338 00339 void OLED::image(int x, int y, int w, int h, const unsigned short *image16) 00340 { 00341 image(x, y, w, h, (unsigned short *) image16); 00342 } 00343 00344 void OLED::image(int x, int y, int w, int h, unsigned char *image8x3) 00345 { 00346 // un-reverse 00347 if (reversal) { 00348 unsigned char cmdN[] = {0xa0, 0x70}; 00349 cmdOut(cmdN, 2); 00350 reversal = false; 00351 } 00352 // setup the region to fill 00353 unsigned char cmd[]={0x15, x, x+w-1, 0x75, y, y+h-1}; 00354 cmdOut(cmd, 6); 00355 // fill up the region with the image data 00356 int size = w * h; 00357 for (int k = 0; k < size; k++) { 00358 unsigned char r, g, b; 00359 b = *image8x3++; 00360 g = *image8x3++; 00361 r = *image8x3++; 00362 unsigned short data16 = color(r, g, b); 00363 dataOut(&data16, 1); 00364 } 00365 // wait 00366 wait_us(100); 00367 } 00368 00369 void OLED::image(int x, int y, int w, int h, const unsigned char *image8x3) 00370 { 00371 image(x, y, w, h, (unsigned char *) image8x3); 00372 } 00373 00374 void OLED::text(int x, int y, char *string, unsigned short color) 00375 { 00376 int len = strlen(string); 00377 for (int i = 0; i < len; i++) { 00378 int xx = x + i * 6; 00379 unsigned char code = string[i]; 00380 if (code < 0x20 || code >= 0x80) continue; 00381 unsigned char *font = font6x8 + ((code - 0x20) * 6); 00382 for (int fx = 0; fx < 6; fx++) { 00383 if (xx + fx > 95) break; 00384 unsigned char line = *(font + fx); 00385 for (int fy = 0, bit = 0x01; fy < 8; fy++, bit <<= 1) { 00386 if (line & bit) point(xx + fx, y + fy, color); 00387 } 00388 } 00389 } 00390 } 00391 00392 void OLED::text(int x, int y, char *string, unsigned short colorF, unsigned short colorB) 00393 { 00394 // clear the background 00395 int w = strlen(string) * 6; 00396 if (x + w > 95) w = 95 - x; 00397 rect(x, y, w, 8, colorB, 1); 00398 // overwrite the text 00399 text(x, y, string, colorF); 00400 }
Generated on Fri Jul 29 2022 15:47:46 by 1.7.2