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@0:76a5ae915f62, 2012-08-17 (annotated)
- Committer:
- xkozima
- Date:
- Fri Aug 17 15:30:29 2012 +0000
- Revision:
- 0:76a5ae915f62
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...
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
xkozima | 0:76a5ae915f62 | 1 | // |
xkozima | 0:76a5ae915f62 | 2 | // OLEDaccel: 96x64 OLED driver |
xkozima | 0:76a5ae915f62 | 3 | // (version 0.2, August 17, 2012) |
xkozima | 0:76a5ae915f62 | 4 | // xkozima@myu.ac.jp |
xkozima | 0:76a5ae915f62 | 5 | |
xkozima | 0:76a5ae915f62 | 6 | #include "OLEDaccel.h" |
xkozima | 0:76a5ae915f62 | 7 | #include "font6x8.h" |
xkozima | 0:76a5ae915f62 | 8 | |
xkozima | 0:76a5ae915f62 | 9 | OLED::OLED (PinName rstPin, PinName csPin, PinName dcPin, PinName mosiPin, PinName sckPin) : |
xkozima | 0:76a5ae915f62 | 10 | rst(rstPin), cs(csPin), dc(dcPin), spi(mosiPin, NC, sckPin) |
xkozima | 0:76a5ae915f62 | 11 | { |
xkozima | 0:76a5ae915f62 | 12 | // setup spi (8bit master @48MHz) |
xkozima | 0:76a5ae915f62 | 13 | spi.format(8,3); |
xkozima | 0:76a5ae915f62 | 14 | spi.frequency(48000000); |
xkozima | 0:76a5ae915f62 | 15 | wait_ms(20); |
xkozima | 0:76a5ae915f62 | 16 | |
xkozima | 0:76a5ae915f62 | 17 | // reset OLED |
xkozima | 0:76a5ae915f62 | 18 | rst = 0; |
xkozima | 0:76a5ae915f62 | 19 | wait_ms(20); |
xkozima | 0:76a5ae915f62 | 20 | rst = 1; |
xkozima | 0:76a5ae915f62 | 21 | wait_ms(20); |
xkozima | 0:76a5ae915f62 | 22 | |
xkozima | 0:76a5ae915f62 | 23 | // init command |
xkozima | 0:76a5ae915f62 | 24 | unsigned char cmd1[] = {0xa0, 0x70}; |
xkozima | 0:76a5ae915f62 | 25 | cmdOut(cmd1, 2); |
xkozima | 0:76a5ae915f62 | 26 | unsigned char cmd2[] = {0xaf}; |
xkozima | 0:76a5ae915f62 | 27 | cmdOut(cmd2, 1); |
xkozima | 0:76a5ae915f62 | 28 | unsigned char cmd3[] = {0x26, 0x01}; |
xkozima | 0:76a5ae915f62 | 29 | cmdOut(cmd3, 2); |
xkozima | 0:76a5ae915f62 | 30 | |
xkozima | 0:76a5ae915f62 | 31 | // clear flags |
xkozima | 0:76a5ae915f62 | 32 | reversal = false; |
xkozima | 0:76a5ae915f62 | 33 | filling = true; |
xkozima | 0:76a5ae915f62 | 34 | |
xkozima | 0:76a5ae915f62 | 35 | // clear and display on |
xkozima | 0:76a5ae915f62 | 36 | rect(0, 0, 96, 64, 0, 1); |
xkozima | 0:76a5ae915f62 | 37 | wait(0.1); |
xkozima | 0:76a5ae915f62 | 38 | cmdOutOne(0xaf); // display on |
xkozima | 0:76a5ae915f62 | 39 | } |
xkozima | 0:76a5ae915f62 | 40 | |
xkozima | 0:76a5ae915f62 | 41 | void OLED::cmdOutOne(unsigned char cmdOne) |
xkozima | 0:76a5ae915f62 | 42 | { |
xkozima | 0:76a5ae915f62 | 43 | dc = 0; |
xkozima | 0:76a5ae915f62 | 44 | cs = 0; |
xkozima | 0:76a5ae915f62 | 45 | spi.write(cmdOne); |
xkozima | 0:76a5ae915f62 | 46 | cs = 1; |
xkozima | 0:76a5ae915f62 | 47 | } |
xkozima | 0:76a5ae915f62 | 48 | |
xkozima | 0:76a5ae915f62 | 49 | void OLED::cmdOut(unsigned char *cmd, int length) |
xkozima | 0:76a5ae915f62 | 50 | { |
xkozima | 0:76a5ae915f62 | 51 | dc = 0; |
xkozima | 0:76a5ae915f62 | 52 | cs = 0; |
xkozima | 0:76a5ae915f62 | 53 | for (int i = 0; i < length; i++) { |
xkozima | 0:76a5ae915f62 | 54 | spi.write(*cmd++); |
xkozima | 0:76a5ae915f62 | 55 | } |
xkozima | 0:76a5ae915f62 | 56 | cs = 1; |
xkozima | 0:76a5ae915f62 | 57 | } |
xkozima | 0:76a5ae915f62 | 58 | |
xkozima | 0:76a5ae915f62 | 59 | void OLED::dataOut(unsigned short *data, int length) |
xkozima | 0:76a5ae915f62 | 60 | { |
xkozima | 0:76a5ae915f62 | 61 | dc = 1; |
xkozima | 0:76a5ae915f62 | 62 | cs = 0; |
xkozima | 0:76a5ae915f62 | 63 | for (int i = 0; i < length; i++) { |
xkozima | 0:76a5ae915f62 | 64 | unsigned short d16 = *data++; |
xkozima | 0:76a5ae915f62 | 65 | spi.write((unsigned char) ((d16 & 0xff00) >> 8)); |
xkozima | 0:76a5ae915f62 | 66 | spi.write((unsigned char) (d16 & 0x00ff)); |
xkozima | 0:76a5ae915f62 | 67 | } |
xkozima | 0:76a5ae915f62 | 68 | cs = 1; |
xkozima | 0:76a5ae915f62 | 69 | } |
xkozima | 0:76a5ae915f62 | 70 | |
xkozima | 0:76a5ae915f62 | 71 | unsigned short OLED::color (int r, int g, int b) |
xkozima | 0:76a5ae915f62 | 72 | { |
xkozima | 0:76a5ae915f62 | 73 | return ((b & 0xf8) << 8) | ((g & 0xfc) << 3) | ((r & 0xf8) >> 3); |
xkozima | 0:76a5ae915f62 | 74 | } |
xkozima | 0:76a5ae915f62 | 75 | |
xkozima | 0:76a5ae915f62 | 76 | void OLED::clear (unsigned short color) |
xkozima | 0:76a5ae915f62 | 77 | { |
xkozima | 0:76a5ae915f62 | 78 | rect(0, 0, 96, 64, color, 1); |
xkozima | 0:76a5ae915f62 | 79 | } |
xkozima | 0:76a5ae915f62 | 80 | |
xkozima | 0:76a5ae915f62 | 81 | void OLED::point(int x, int y, unsigned short color) |
xkozima | 0:76a5ae915f62 | 82 | { |
xkozima | 0:76a5ae915f62 | 83 | // draw a point (a small rectangle/filled) |
xkozima | 0:76a5ae915f62 | 84 | unsigned char c1 = (color & 0xf800) >> 10, |
xkozima | 0:76a5ae915f62 | 85 | c2 = (color & 0x07e0) >> 5, |
xkozima | 0:76a5ae915f62 | 86 | c3 = (color & 0x001f) << 1; |
xkozima | 0:76a5ae915f62 | 87 | unsigned char cmd[] = {0x22, x, y, x, y, |
xkozima | 0:76a5ae915f62 | 88 | c1, c2, c3, c1, c2, c3 }; |
xkozima | 0:76a5ae915f62 | 89 | cmdOut(cmd, 11); |
xkozima | 0:76a5ae915f62 | 90 | } |
xkozima | 0:76a5ae915f62 | 91 | |
xkozima | 0:76a5ae915f62 | 92 | void OLED::rect (int x, int y, int w, int h, |
xkozima | 0:76a5ae915f62 | 93 | unsigned short color, int fill ) |
xkozima | 0:76a5ae915f62 | 94 | { |
xkozima | 0:76a5ae915f62 | 95 | unsigned char c1 = (color & 0xf800) >> 10, |
xkozima | 0:76a5ae915f62 | 96 | c2 = (color & 0x07e0) >> 5, |
xkozima | 0:76a5ae915f62 | 97 | c3 = (color & 0x001f) << 1; |
xkozima | 0:76a5ae915f62 | 98 | // |
xkozima | 0:76a5ae915f62 | 99 | // fill or no fill |
xkozima | 0:76a5ae915f62 | 100 | if (fill) { |
xkozima | 0:76a5ae915f62 | 101 | if (! filling) { |
xkozima | 0:76a5ae915f62 | 102 | unsigned char cmdF[] = {0x26, 1}; |
xkozima | 0:76a5ae915f62 | 103 | cmdOut(cmdF, 2); |
xkozima | 0:76a5ae915f62 | 104 | filling = true; |
xkozima | 0:76a5ae915f62 | 105 | } |
xkozima | 0:76a5ae915f62 | 106 | } |
xkozima | 0:76a5ae915f62 | 107 | else { |
xkozima | 0:76a5ae915f62 | 108 | if (filling) { |
xkozima | 0:76a5ae915f62 | 109 | unsigned char cmdN[] = {0x26, 0}; |
xkozima | 0:76a5ae915f62 | 110 | cmdOut(cmdN, 2); |
xkozima | 0:76a5ae915f62 | 111 | filling = false; |
xkozima | 0:76a5ae915f62 | 112 | } |
xkozima | 0:76a5ae915f62 | 113 | } |
xkozima | 0:76a5ae915f62 | 114 | // un-reverse |
xkozima | 0:76a5ae915f62 | 115 | if (reversal) { |
xkozima | 0:76a5ae915f62 | 116 | unsigned char cmdN[] = {0xa0, 0x70}; |
xkozima | 0:76a5ae915f62 | 117 | cmdOut(cmdN, 2); |
xkozima | 0:76a5ae915f62 | 118 | reversal = false; |
xkozima | 0:76a5ae915f62 | 119 | } |
xkozima | 0:76a5ae915f62 | 120 | // draw/fill the rectangle |
xkozima | 0:76a5ae915f62 | 121 | unsigned char cmd[] = {0x22, x, y, x + w - 1, y + h - 1, |
xkozima | 0:76a5ae915f62 | 122 | c1, c2, c3, c1, c2, c3 }; |
xkozima | 0:76a5ae915f62 | 123 | cmdOut(cmd, 11); |
xkozima | 0:76a5ae915f62 | 124 | // wait |
xkozima | 0:76a5ae915f62 | 125 | wait_us(w * h / 10); |
xkozima | 0:76a5ae915f62 | 126 | } |
xkozima | 0:76a5ae915f62 | 127 | |
xkozima | 0:76a5ae915f62 | 128 | void OLED::line(int x1, int y1, int x2, int y2, unsigned short color) |
xkozima | 0:76a5ae915f62 | 129 | { |
xkozima | 0:76a5ae915f62 | 130 | unsigned char c1 = (color & 0xf800) >> 10, |
xkozima | 0:76a5ae915f62 | 131 | c2 = (color & 0x07e0) >> 5, |
xkozima | 0:76a5ae915f62 | 132 | c3 = (color & 0x001f) << 1; |
xkozima | 0:76a5ae915f62 | 133 | if (x1 < x2) { |
xkozima | 0:76a5ae915f62 | 134 | if (y1 < y2) { |
xkozima | 0:76a5ae915f62 | 135 | // normal |
xkozima | 0:76a5ae915f62 | 136 | unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3}; |
xkozima | 0:76a5ae915f62 | 137 | if (reversal) { |
xkozima | 0:76a5ae915f62 | 138 | unsigned char cmdN[] = {0xa0, 0x70}; |
xkozima | 0:76a5ae915f62 | 139 | cmdOut(cmdN, 2); |
xkozima | 0:76a5ae915f62 | 140 | reversal = false; |
xkozima | 0:76a5ae915f62 | 141 | } |
xkozima | 0:76a5ae915f62 | 142 | cmdOut(cmd, 8); |
xkozima | 0:76a5ae915f62 | 143 | } |
xkozima | 0:76a5ae915f62 | 144 | else if (y1 > y2) { |
xkozima | 0:76a5ae915f62 | 145 | // reversal |
xkozima | 0:76a5ae915f62 | 146 | if (! reversal) { |
xkozima | 0:76a5ae915f62 | 147 | unsigned char cmdR[] = {0xa0, 0x72}; |
xkozima | 0:76a5ae915f62 | 148 | cmdOut(cmdR, 2); |
xkozima | 0:76a5ae915f62 | 149 | reversal = true; |
xkozima | 0:76a5ae915f62 | 150 | } |
xkozima | 0:76a5ae915f62 | 151 | unsigned char cmd[] = {0x21, 95 - x2, y2, 95 - x1, y1, c1, c2, c3}; |
xkozima | 0:76a5ae915f62 | 152 | cmdOut(cmd, 8); |
xkozima | 0:76a5ae915f62 | 153 | } |
xkozima | 0:76a5ae915f62 | 154 | else { // y1 == y2 |
xkozima | 0:76a5ae915f62 | 155 | // normal |
xkozima | 0:76a5ae915f62 | 156 | unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3}; |
xkozima | 0:76a5ae915f62 | 157 | if (reversal) { |
xkozima | 0:76a5ae915f62 | 158 | unsigned char cmdN[] = {0xa0, 0x70}; |
xkozima | 0:76a5ae915f62 | 159 | cmdOut(cmdN, 2); |
xkozima | 0:76a5ae915f62 | 160 | reversal = false; |
xkozima | 0:76a5ae915f62 | 161 | } |
xkozima | 0:76a5ae915f62 | 162 | cmdOut(cmd, 8); |
xkozima | 0:76a5ae915f62 | 163 | } |
xkozima | 0:76a5ae915f62 | 164 | } |
xkozima | 0:76a5ae915f62 | 165 | else if (x1 > x2) { |
xkozima | 0:76a5ae915f62 | 166 | if (y1 < y2) { |
xkozima | 0:76a5ae915f62 | 167 | // reversal |
xkozima | 0:76a5ae915f62 | 168 | if (! reversal) { |
xkozima | 0:76a5ae915f62 | 169 | unsigned char cmdR[] = {0xa0, 0x72}; |
xkozima | 0:76a5ae915f62 | 170 | cmdOut(cmdR, 2); |
xkozima | 0:76a5ae915f62 | 171 | reversal = true; |
xkozima | 0:76a5ae915f62 | 172 | } |
xkozima | 0:76a5ae915f62 | 173 | unsigned char cmd[] = {0x21, 95 - x2, y2, 95 - x1, y1, c1, c2, c3}; |
xkozima | 0:76a5ae915f62 | 174 | cmdOut(cmd, 8); |
xkozima | 0:76a5ae915f62 | 175 | } |
xkozima | 0:76a5ae915f62 | 176 | else if (y1 > y2) { |
xkozima | 0:76a5ae915f62 | 177 | // normal |
xkozima | 0:76a5ae915f62 | 178 | unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3}; |
xkozima | 0:76a5ae915f62 | 179 | if (reversal) { |
xkozima | 0:76a5ae915f62 | 180 | unsigned char cmdN[] = {0xa0, 0x70}; |
xkozima | 0:76a5ae915f62 | 181 | cmdOut(cmdN, 2); |
xkozima | 0:76a5ae915f62 | 182 | reversal = false; |
xkozima | 0:76a5ae915f62 | 183 | } |
xkozima | 0:76a5ae915f62 | 184 | cmdOut(cmd, 8); |
xkozima | 0:76a5ae915f62 | 185 | } |
xkozima | 0:76a5ae915f62 | 186 | else { // y1 == y2 |
xkozima | 0:76a5ae915f62 | 187 | // reversal |
xkozima | 0:76a5ae915f62 | 188 | unsigned char cmd[] = {0xa0, 0x72, |
xkozima | 0:76a5ae915f62 | 189 | 0x21, 95 - x2, y2, 95 - x1, y1, c1, c2, c3, |
xkozima | 0:76a5ae915f62 | 190 | 0xa0, 0x70 }; |
xkozima | 0:76a5ae915f62 | 191 | cmdOut(cmd, 12); |
xkozima | 0:76a5ae915f62 | 192 | } |
xkozima | 0:76a5ae915f62 | 193 | } |
xkozima | 0:76a5ae915f62 | 194 | else { // x1 == x2 |
xkozima | 0:76a5ae915f62 | 195 | if (y1 < y2) { |
xkozima | 0:76a5ae915f62 | 196 | // normal |
xkozima | 0:76a5ae915f62 | 197 | unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3}; |
xkozima | 0:76a5ae915f62 | 198 | if (reversal) { |
xkozima | 0:76a5ae915f62 | 199 | unsigned char cmdN[] = {0xa0, 0x70}; |
xkozima | 0:76a5ae915f62 | 200 | cmdOut(cmdN, 2); |
xkozima | 0:76a5ae915f62 | 201 | reversal = false; |
xkozima | 0:76a5ae915f62 | 202 | } |
xkozima | 0:76a5ae915f62 | 203 | cmdOut(cmd, 8); |
xkozima | 0:76a5ae915f62 | 204 | } |
xkozima | 0:76a5ae915f62 | 205 | else if (y1 > y2) { |
xkozima | 0:76a5ae915f62 | 206 | // normal (force downward) |
xkozima | 0:76a5ae915f62 | 207 | unsigned char cmd[] = {0x21, x2, y2, x1, y1, c1, c2, c3}; |
xkozima | 0:76a5ae915f62 | 208 | cmdOut(cmd, 8); |
xkozima | 0:76a5ae915f62 | 209 | } |
xkozima | 0:76a5ae915f62 | 210 | else { // y1 == y2 |
xkozima | 0:76a5ae915f62 | 211 | // normal (point) |
xkozima | 0:76a5ae915f62 | 212 | unsigned char cmd[] = {0x21, x1, y1, x2, y2, c1, c2, c3}; |
xkozima | 0:76a5ae915f62 | 213 | if (reversal) { |
xkozima | 0:76a5ae915f62 | 214 | unsigned char cmdN[] = {0xa0, 0x70}; |
xkozima | 0:76a5ae915f62 | 215 | cmdOut(cmdN, 2); |
xkozima | 0:76a5ae915f62 | 216 | reversal = false; |
xkozima | 0:76a5ae915f62 | 217 | } |
xkozima | 0:76a5ae915f62 | 218 | cmdOut(cmd, 8); |
xkozima | 0:76a5ae915f62 | 219 | } |
xkozima | 0:76a5ae915f62 | 220 | } |
xkozima | 0:76a5ae915f62 | 221 | // wait |
xkozima | 0:76a5ae915f62 | 222 | wait_us(1); |
xkozima | 0:76a5ae915f62 | 223 | } |
xkozima | 0:76a5ae915f62 | 224 | |
xkozima | 0:76a5ae915f62 | 225 | void OLED::circle(int x, int y, int r, unsigned short color, int fill) |
xkozima | 0:76a5ae915f62 | 226 | { |
xkozima | 0:76a5ae915f62 | 227 | // exception |
xkozima | 0:76a5ae915f62 | 228 | if (r < 1) { |
xkozima | 0:76a5ae915f62 | 229 | line(x, y, x, y, color); |
xkozima | 0:76a5ae915f62 | 230 | return; |
xkozima | 0:76a5ae915f62 | 231 | } else if (r == 1) { |
xkozima | 0:76a5ae915f62 | 232 | rect(x - 1, y - 1, 3, 3, color, fill); |
xkozima | 0:76a5ae915f62 | 233 | return; |
xkozima | 0:76a5ae915f62 | 234 | } |
xkozima | 0:76a5ae915f62 | 235 | // ok, go |
xkozima | 0:76a5ae915f62 | 236 | int xx = 0, |
xkozima | 0:76a5ae915f62 | 237 | yy = r, |
xkozima | 0:76a5ae915f62 | 238 | err = 2 - 2 * r; |
xkozima | 0:76a5ae915f62 | 239 | // iteration |
xkozima | 0:76a5ae915f62 | 240 | do { |
xkozima | 0:76a5ae915f62 | 241 | // draw it! |
xkozima | 0:76a5ae915f62 | 242 | if (fill) { |
xkozima | 0:76a5ae915f62 | 243 | line(x + xx, y + yy, x + xx, y, color); |
xkozima | 0:76a5ae915f62 | 244 | line(x - xx, y + yy, x, y + yy, color); |
xkozima | 0:76a5ae915f62 | 245 | line(x - xx, y - yy, x - xx, y, color); |
xkozima | 0:76a5ae915f62 | 246 | line(x + xx, y - yy, x, y - yy, color); |
xkozima | 0:76a5ae915f62 | 247 | } |
xkozima | 0:76a5ae915f62 | 248 | else { |
xkozima | 0:76a5ae915f62 | 249 | point(x + xx, y + yy, color); |
xkozima | 0:76a5ae915f62 | 250 | point(x - xx, y + yy, color); |
xkozima | 0:76a5ae915f62 | 251 | point(x - xx, y - yy, color); |
xkozima | 0:76a5ae915f62 | 252 | point(x + xx, y - yy, color); |
xkozima | 0:76a5ae915f62 | 253 | } |
xkozima | 0:76a5ae915f62 | 254 | // walk |
xkozima | 0:76a5ae915f62 | 255 | if (err > -yy) { |
xkozima | 0:76a5ae915f62 | 256 | yy--; |
xkozima | 0:76a5ae915f62 | 257 | err += 1 - 2 * yy; |
xkozima | 0:76a5ae915f62 | 258 | } |
xkozima | 0:76a5ae915f62 | 259 | if (err <= xx) { |
xkozima | 0:76a5ae915f62 | 260 | xx++; |
xkozima | 0:76a5ae915f62 | 261 | err += 1 + 2 * xx; |
xkozima | 0:76a5ae915f62 | 262 | } |
xkozima | 0:76a5ae915f62 | 263 | } while (yy >= 0); |
xkozima | 0:76a5ae915f62 | 264 | } |
xkozima | 0:76a5ae915f62 | 265 | |
xkozima | 0:76a5ae915f62 | 266 | void OLED::ellipse(int x, int y, int rx, int ry, unsigned short color, int fill) |
xkozima | 0:76a5ae915f62 | 267 | { |
xkozima | 0:76a5ae915f62 | 268 | // exception |
xkozima | 0:76a5ae915f62 | 269 | if (rx < 1) { |
xkozima | 0:76a5ae915f62 | 270 | line(x, y - ry, x, y + ry, color); |
xkozima | 0:76a5ae915f62 | 271 | return; |
xkozima | 0:76a5ae915f62 | 272 | } |
xkozima | 0:76a5ae915f62 | 273 | else if (ry < 1) { |
xkozima | 0:76a5ae915f62 | 274 | line(x - rx, y, x + rx, y, color); |
xkozima | 0:76a5ae915f62 | 275 | return; |
xkozima | 0:76a5ae915f62 | 276 | } |
xkozima | 0:76a5ae915f62 | 277 | // ok, go |
xkozima | 0:76a5ae915f62 | 278 | int xx = -rx, yy = 0; |
xkozima | 0:76a5ae915f62 | 279 | int e2 = ry, |
xkozima | 0:76a5ae915f62 | 280 | dx = (2 * xx + 1) * e2 * e2, |
xkozima | 0:76a5ae915f62 | 281 | dy = xx * xx, |
xkozima | 0:76a5ae915f62 | 282 | err = dx + dy; |
xkozima | 0:76a5ae915f62 | 283 | do { |
xkozima | 0:76a5ae915f62 | 284 | if (fill) { |
xkozima | 0:76a5ae915f62 | 285 | line(x + xx, y + yy, x + xx, y, color); |
xkozima | 0:76a5ae915f62 | 286 | line(x - xx, y + yy, x, y + yy, color); |
xkozima | 0:76a5ae915f62 | 287 | line(x - xx, y - yy, x - xx, y, color); |
xkozima | 0:76a5ae915f62 | 288 | line(x + xx, y - yy, x, y - yy, color); |
xkozima | 0:76a5ae915f62 | 289 | } |
xkozima | 0:76a5ae915f62 | 290 | else { |
xkozima | 0:76a5ae915f62 | 291 | point(x + xx, y + yy, color); |
xkozima | 0:76a5ae915f62 | 292 | point(x - xx, y + yy, color); |
xkozima | 0:76a5ae915f62 | 293 | point(x - xx, y - yy, color); |
xkozima | 0:76a5ae915f62 | 294 | point(x + xx, y - yy, color); |
xkozima | 0:76a5ae915f62 | 295 | } |
xkozima | 0:76a5ae915f62 | 296 | e2 = 2 * err; |
xkozima | 0:76a5ae915f62 | 297 | if (e2 >= dx) { |
xkozima | 0:76a5ae915f62 | 298 | xx++; |
xkozima | 0:76a5ae915f62 | 299 | dx += 2 * ry * ry; |
xkozima | 0:76a5ae915f62 | 300 | err += dx; |
xkozima | 0:76a5ae915f62 | 301 | } |
xkozima | 0:76a5ae915f62 | 302 | if (e2 <= dy) { |
xkozima | 0:76a5ae915f62 | 303 | yy++; |
xkozima | 0:76a5ae915f62 | 304 | dy += 2 * rx * rx; |
xkozima | 0:76a5ae915f62 | 305 | err += dy; |
xkozima | 0:76a5ae915f62 | 306 | } |
xkozima | 0:76a5ae915f62 | 307 | } while (xx <= 0); |
xkozima | 0:76a5ae915f62 | 308 | if (fill) { |
xkozima | 0:76a5ae915f62 | 309 | while (yy++ < ry) { |
xkozima | 0:76a5ae915f62 | 310 | line(x, y + yy, x, y, color); |
xkozima | 0:76a5ae915f62 | 311 | line(x, y - yy, x, y, color); |
xkozima | 0:76a5ae915f62 | 312 | } |
xkozima | 0:76a5ae915f62 | 313 | } |
xkozima | 0:76a5ae915f62 | 314 | else { |
xkozima | 0:76a5ae915f62 | 315 | while (yy++ < ry) { |
xkozima | 0:76a5ae915f62 | 316 | point(x, y + yy, color); |
xkozima | 0:76a5ae915f62 | 317 | point(x, y - yy, color); |
xkozima | 0:76a5ae915f62 | 318 | } |
xkozima | 0:76a5ae915f62 | 319 | } |
xkozima | 0:76a5ae915f62 | 320 | } |
xkozima | 0:76a5ae915f62 | 321 | |
xkozima | 0:76a5ae915f62 | 322 | void OLED::image(int x, int y, int w, int h, unsigned short *image16) |
xkozima | 0:76a5ae915f62 | 323 | { |
xkozima | 0:76a5ae915f62 | 324 | // un-reverse |
xkozima | 0:76a5ae915f62 | 325 | if (reversal) { |
xkozima | 0:76a5ae915f62 | 326 | unsigned char cmdN[] = {0xa0, 0x70}; |
xkozima | 0:76a5ae915f62 | 327 | cmdOut(cmdN, 2); |
xkozima | 0:76a5ae915f62 | 328 | reversal = false; |
xkozima | 0:76a5ae915f62 | 329 | } |
xkozima | 0:76a5ae915f62 | 330 | // setup the region to fill |
xkozima | 0:76a5ae915f62 | 331 | unsigned char cmd[]={0x15, x, x+w-1, 0x75, y, y+h-1}; |
xkozima | 0:76a5ae915f62 | 332 | cmdOut(cmd, 6); |
xkozima | 0:76a5ae915f62 | 333 | // fill up the region with the image data |
xkozima | 0:76a5ae915f62 | 334 | dataOut(image16, w * h); |
xkozima | 0:76a5ae915f62 | 335 | // wait |
xkozima | 0:76a5ae915f62 | 336 | wait_us(100); |
xkozima | 0:76a5ae915f62 | 337 | } |
xkozima | 0:76a5ae915f62 | 338 | |
xkozima | 0:76a5ae915f62 | 339 | void OLED::image(int x, int y, int w, int h, const unsigned short *image16) |
xkozima | 0:76a5ae915f62 | 340 | { |
xkozima | 0:76a5ae915f62 | 341 | image(x, y, w, h, (unsigned short *) image16); |
xkozima | 0:76a5ae915f62 | 342 | } |
xkozima | 0:76a5ae915f62 | 343 | |
xkozima | 0:76a5ae915f62 | 344 | void OLED::image(int x, int y, int w, int h, unsigned char *image8x3) |
xkozima | 0:76a5ae915f62 | 345 | { |
xkozima | 0:76a5ae915f62 | 346 | // un-reverse |
xkozima | 0:76a5ae915f62 | 347 | if (reversal) { |
xkozima | 0:76a5ae915f62 | 348 | unsigned char cmdN[] = {0xa0, 0x70}; |
xkozima | 0:76a5ae915f62 | 349 | cmdOut(cmdN, 2); |
xkozima | 0:76a5ae915f62 | 350 | reversal = false; |
xkozima | 0:76a5ae915f62 | 351 | } |
xkozima | 0:76a5ae915f62 | 352 | // setup the region to fill |
xkozima | 0:76a5ae915f62 | 353 | unsigned char cmd[]={0x15, x, x+w-1, 0x75, y, y+h-1}; |
xkozima | 0:76a5ae915f62 | 354 | cmdOut(cmd, 6); |
xkozima | 0:76a5ae915f62 | 355 | // fill up the region with the image data |
xkozima | 0:76a5ae915f62 | 356 | int size = w * h; |
xkozima | 0:76a5ae915f62 | 357 | for (int k = 0; k < size; k++) { |
xkozima | 0:76a5ae915f62 | 358 | unsigned char r, g, b; |
xkozima | 0:76a5ae915f62 | 359 | b = *image8x3++; |
xkozima | 0:76a5ae915f62 | 360 | g = *image8x3++; |
xkozima | 0:76a5ae915f62 | 361 | r = *image8x3++; |
xkozima | 0:76a5ae915f62 | 362 | unsigned short data16 = color(r, g, b); |
xkozima | 0:76a5ae915f62 | 363 | dataOut(&data16, 1); |
xkozima | 0:76a5ae915f62 | 364 | } |
xkozima | 0:76a5ae915f62 | 365 | // wait |
xkozima | 0:76a5ae915f62 | 366 | wait_us(100); |
xkozima | 0:76a5ae915f62 | 367 | } |
xkozima | 0:76a5ae915f62 | 368 | |
xkozima | 0:76a5ae915f62 | 369 | void OLED::image(int x, int y, int w, int h, const unsigned char *image8x3) |
xkozima | 0:76a5ae915f62 | 370 | { |
xkozima | 0:76a5ae915f62 | 371 | image(x, y, w, h, (unsigned char *) image8x3); |
xkozima | 0:76a5ae915f62 | 372 | } |
xkozima | 0:76a5ae915f62 | 373 | |
xkozima | 0:76a5ae915f62 | 374 | void OLED::text(int x, int y, char *string, unsigned short color) |
xkozima | 0:76a5ae915f62 | 375 | { |
xkozima | 0:76a5ae915f62 | 376 | int len = strlen(string); |
xkozima | 0:76a5ae915f62 | 377 | for (int i = 0; i < len; i++) { |
xkozima | 0:76a5ae915f62 | 378 | int xx = x + i * 6; |
xkozima | 0:76a5ae915f62 | 379 | unsigned char code = string[i]; |
xkozima | 0:76a5ae915f62 | 380 | if (code < 0x20 || code >= 0x80) continue; |
xkozima | 0:76a5ae915f62 | 381 | unsigned char *font = font6x8 + ((code - 0x20) * 6); |
xkozima | 0:76a5ae915f62 | 382 | for (int fx = 0; fx < 6; fx++) { |
xkozima | 0:76a5ae915f62 | 383 | if (xx + fx > 95) break; |
xkozima | 0:76a5ae915f62 | 384 | unsigned char line = *(font + fx); |
xkozima | 0:76a5ae915f62 | 385 | for (int fy = 0, bit = 0x01; fy < 8; fy++, bit <<= 1) { |
xkozima | 0:76a5ae915f62 | 386 | if (line & bit) point(xx + fx, y + fy, color); |
xkozima | 0:76a5ae915f62 | 387 | } |
xkozima | 0:76a5ae915f62 | 388 | } |
xkozima | 0:76a5ae915f62 | 389 | } |
xkozima | 0:76a5ae915f62 | 390 | } |
xkozima | 0:76a5ae915f62 | 391 | |
xkozima | 0:76a5ae915f62 | 392 | void OLED::text(int x, int y, char *string, unsigned short colorF, unsigned short colorB) |
xkozima | 0:76a5ae915f62 | 393 | { |
xkozima | 0:76a5ae915f62 | 394 | // clear the background |
xkozima | 0:76a5ae915f62 | 395 | int w = strlen(string) * 6; |
xkozima | 0:76a5ae915f62 | 396 | if (x + w > 95) w = 95 - x; |
xkozima | 0:76a5ae915f62 | 397 | rect(x, y, w, 8, colorB, 1); |
xkozima | 0:76a5ae915f62 | 398 | // overwrite the text |
xkozima | 0:76a5ae915f62 | 399 | text(x, y, string, colorF); |
xkozima | 0:76a5ae915f62 | 400 | } |