EA OLED (Orig. by SFord, retouched by Lerche)

Dependencies:   mbed

Committer:
Lerche
Date:
Sun Oct 03 08:36:08 2010 +0000
Revision:
0:69334bd84891

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Lerche 0:69334bd84891 1 // test library for Embedded Artists OLED used on Xpresso Baseboard
Lerche 0:69334bd84891 2
Lerche 0:69334bd84891 3 #include "EAOLED.h"
Lerche 0:69334bd84891 4 #include "mbed.h"
Lerche 0:69334bd84891 5
Lerche 0:69334bd84891 6 EAOLED::EAOLED(PinName mosi, PinName dnc, PinName sclk, PinName cs, PinName power)
Lerche 0:69334bd84891 7 : _spi(mosi, NC, sclk), _data(dnc), _cs(cs), _power(power) {
Lerche 0:69334bd84891 8 reset();
Lerche 0:69334bd84891 9 }
Lerche 0:69334bd84891 10
Lerche 0:69334bd84891 11 void EAOLED::command(int value) {
Lerche 0:69334bd84891 12 _data = 0;
Lerche 0:69334bd84891 13 _cs = 0;
Lerche 0:69334bd84891 14 _spi.write(value);
Lerche 0:69334bd84891 15 _cs = 1;
Lerche 0:69334bd84891 16 }
Lerche 0:69334bd84891 17
Lerche 0:69334bd84891 18 void EAOLED::data(int value) {
Lerche 0:69334bd84891 19 _data = 1;
Lerche 0:69334bd84891 20 _cs = 0;
Lerche 0:69334bd84891 21 _spi.write(value);
Lerche 0:69334bd84891 22 _cs = 1;
Lerche 0:69334bd84891 23 }
Lerche 0:69334bd84891 24
Lerche 0:69334bd84891 25 void EAOLED::reset() {
Lerche 0:69334bd84891 26 _power = 0;
Lerche 0:69334bd84891 27 _cs = 1;
Lerche 0:69334bd84891 28
Lerche 0:69334bd84891 29 // Startup sequence recommended by embedded artists baseboard reference code
Lerche 0:69334bd84891 30 command(0x02); // set low column address
Lerche 0:69334bd84891 31 command(0x12); // set high column address
Lerche 0:69334bd84891 32 command(0x40); // display start set
Lerche 0:69334bd84891 33 command(0x2e); // stop horzontal scroll
Lerche 0:69334bd84891 34 command(0x81); // set contrast control register
Lerche 0:69334bd84891 35 command(0x32); //
Lerche 0:69334bd84891 36 command(0x82); // brightness for color banks
Lerche 0:69334bd84891 37 command(0x80); // display on
Lerche 0:69334bd84891 38 command(0xa1); // set segment re-map
Lerche 0:69334bd84891 39 command(0xa6); // set normal/inverse display
Lerche 0:69334bd84891 40 command(0xa8); // set multiplex ratio
Lerche 0:69334bd84891 41 command(0x3F); //
Lerche 0:69334bd84891 42 command(0xd3); // set display offset
Lerche 0:69334bd84891 43 command(0x40); //
Lerche 0:69334bd84891 44 command(0xad); // set dc-dc on/off
Lerche 0:69334bd84891 45 command(0x8E); //
Lerche 0:69334bd84891 46 command(0xc8); // set com output scan direction
Lerche 0:69334bd84891 47 command(0xd5); // set display clock divide ratio/oscillator/frequency
Lerche 0:69334bd84891 48 command(0xf0); //
Lerche 0:69334bd84891 49 command(0xd8); // set area color mode on/off & low power display mode
Lerche 0:69334bd84891 50 command(0x05); //
Lerche 0:69334bd84891 51 command(0xd9); // set pre-charge period
Lerche 0:69334bd84891 52 command(0xF1); //
Lerche 0:69334bd84891 53 command(0xda); // set com pins hardware configuration
Lerche 0:69334bd84891 54 command(0x12); //
Lerche 0:69334bd84891 55 command(0xdb); // set vcom deselect level
Lerche 0:69334bd84891 56 command(0x34); //
Lerche 0:69334bd84891 57 command(0x91); // set look up table for area color
Lerche 0:69334bd84891 58 command(0x3f); //
Lerche 0:69334bd84891 59 command(0x3f); //
Lerche 0:69334bd84891 60 command(0x3f); //
Lerche 0:69334bd84891 61 command(0x3f); //
Lerche 0:69334bd84891 62 command(0xaf); // display on
Lerche 0:69334bd84891 63 command(0xa4); // display on
Lerche 0:69334bd84891 64
Lerche 0:69334bd84891 65 wait_us(10);
Lerche 0:69334bd84891 66
Lerche 0:69334bd84891 67 _power = 1;
Lerche 0:69334bd84891 68 }
Lerche 0:69334bd84891 69
Lerche 0:69334bd84891 70 #define OLED_DISPLAY_WIDTH 96
Lerche 0:69334bd84891 71 #define OLED_DISPLAY_HEIGHT 64
Lerche 0:69334bd84891 72
Lerche 0:69334bd84891 73 void EAOLED::pixel(int x, int y, int colour) {
Lerche 0:69334bd84891 74 int page = y >> 3;
Lerche 0:69334bd84891 75 int address = 18 + x;
Lerche 0:69334bd84891 76
Lerche 0:69334bd84891 77 int lo = (address >> 0) & 0x0F;
Lerche 0:69334bd84891 78 int hi = (address >> 4) | 0x10;
Lerche 0:69334bd84891 79 int mask = 1 << (y & 0x7);
Lerche 0:69334bd84891 80 int byte = page * OLED_DISPLAY_WIDTH + x;
Lerche 0:69334bd84891 81
Lerche 0:69334bd84891 82 if(colour) {
Lerche 0:69334bd84891 83 framebuffer[byte] |= mask;
Lerche 0:69334bd84891 84 } else {
Lerche 0:69334bd84891 85 framebuffer[byte] &= ~mask;
Lerche 0:69334bd84891 86 }
Lerche 0:69334bd84891 87
Lerche 0:69334bd84891 88 command(0xB0 + page);
Lerche 0:69334bd84891 89 command(lo);
Lerche 0:69334bd84891 90 command(hi);
Lerche 0:69334bd84891 91 data(framebuffer[byte]);
Lerche 0:69334bd84891 92 }
Lerche 0:69334bd84891 93
Lerche 0:69334bd84891 94 void EAOLED::circle(int x0, int y0, int r, int colour) {
Lerche 0:69334bd84891 95
Lerche 0:69334bd84891 96 #define OLED_DISPLAY_WIDTH 96
Lerche 0:69334bd84891 97 #define OLED_DISPLAY_HEIGHT 64
Lerche 0:69334bd84891 98
Lerche 0:69334bd84891 99 int draw_x0, draw_y0;
Lerche 0:69334bd84891 100 int draw_x1, draw_y1;
Lerche 0:69334bd84891 101 int draw_x2, draw_y2;
Lerche 0:69334bd84891 102 int draw_x3, draw_y3;
Lerche 0:69334bd84891 103 int draw_x4, draw_y4;
Lerche 0:69334bd84891 104 int draw_x5, draw_y5;
Lerche 0:69334bd84891 105 int draw_x6, draw_y6;
Lerche 0:69334bd84891 106 int draw_x7, draw_y7;
Lerche 0:69334bd84891 107 int xx, yy;
Lerche 0:69334bd84891 108 int di;
Lerche 0:69334bd84891 109
Lerche 0:69334bd84891 110 if(r == 0) /* no radius */
Lerche 0:69334bd84891 111 {
Lerche 0:69334bd84891 112 return;
Lerche 0:69334bd84891 113 }
Lerche 0:69334bd84891 114
Lerche 0:69334bd84891 115 draw_x0 = draw_x1 = x0;
Lerche 0:69334bd84891 116 draw_y0 = draw_y1 = y0 + r;
Lerche 0:69334bd84891 117 if(draw_y0 < OLED_DISPLAY_HEIGHT)
Lerche 0:69334bd84891 118 {
Lerche 0:69334bd84891 119 pixel(draw_x0, draw_y0, colour); /* 90 degree */
Lerche 0:69334bd84891 120 }
Lerche 0:69334bd84891 121
Lerche 0:69334bd84891 122 draw_x2 = draw_x3 = x0;
Lerche 0:69334bd84891 123 draw_y2 = draw_y3 = y0 - r;
Lerche 0:69334bd84891 124 if(draw_y2 >= 0)
Lerche 0:69334bd84891 125 {
Lerche 0:69334bd84891 126 pixel(draw_x2, draw_y2, colour); /* 270 degree */
Lerche 0:69334bd84891 127 }
Lerche 0:69334bd84891 128
Lerche 0:69334bd84891 129 draw_x4 = draw_x6 = x0 + r;
Lerche 0:69334bd84891 130 draw_y4 = draw_y6 = y0;
Lerche 0:69334bd84891 131 if(draw_x4 < OLED_DISPLAY_WIDTH)
Lerche 0:69334bd84891 132 {
Lerche 0:69334bd84891 133 pixel(draw_x4, draw_y4, colour); /* 0 degree */
Lerche 0:69334bd84891 134 }
Lerche 0:69334bd84891 135
Lerche 0:69334bd84891 136 draw_x5 = draw_x7 = x0 - r;
Lerche 0:69334bd84891 137 draw_y5 = draw_y7 = y0;
Lerche 0:69334bd84891 138 if(draw_x5>=0)
Lerche 0:69334bd84891 139 {
Lerche 0:69334bd84891 140 pixel(draw_x5, draw_y5, colour); /* 180 degree */
Lerche 0:69334bd84891 141 }
Lerche 0:69334bd84891 142
Lerche 0:69334bd84891 143 if(r == 1)
Lerche 0:69334bd84891 144 {
Lerche 0:69334bd84891 145 return;
Lerche 0:69334bd84891 146 }
Lerche 0:69334bd84891 147
Lerche 0:69334bd84891 148 di = 3 - 2*r;
Lerche 0:69334bd84891 149 xx = 0;
Lerche 0:69334bd84891 150 yy = r;
Lerche 0:69334bd84891 151 while(xx < yy)
Lerche 0:69334bd84891 152 {
Lerche 0:69334bd84891 153
Lerche 0:69334bd84891 154 if(di < 0)
Lerche 0:69334bd84891 155 {
Lerche 0:69334bd84891 156 di += 4*xx + 6;
Lerche 0:69334bd84891 157 }
Lerche 0:69334bd84891 158 else
Lerche 0:69334bd84891 159 {
Lerche 0:69334bd84891 160 di += 4*(xx - yy) + 10;
Lerche 0:69334bd84891 161 yy--;
Lerche 0:69334bd84891 162 draw_y0--;
Lerche 0:69334bd84891 163 draw_y1--;
Lerche 0:69334bd84891 164 draw_y2++;
Lerche 0:69334bd84891 165 draw_y3++;
Lerche 0:69334bd84891 166 draw_x4--;
Lerche 0:69334bd84891 167 draw_x5++;
Lerche 0:69334bd84891 168 draw_x6--;
Lerche 0:69334bd84891 169 draw_x7++;
Lerche 0:69334bd84891 170 }
Lerche 0:69334bd84891 171 xx++;
Lerche 0:69334bd84891 172 draw_x0++;
Lerche 0:69334bd84891 173 draw_x1--;
Lerche 0:69334bd84891 174 draw_x2++;
Lerche 0:69334bd84891 175 draw_x3--;
Lerche 0:69334bd84891 176 draw_y4++;
Lerche 0:69334bd84891 177 draw_y5++;
Lerche 0:69334bd84891 178 draw_y6--;
Lerche 0:69334bd84891 179 draw_y7--;
Lerche 0:69334bd84891 180
Lerche 0:69334bd84891 181 if( (draw_x0 <= OLED_DISPLAY_WIDTH) && (draw_y0>=0) )
Lerche 0:69334bd84891 182 {
Lerche 0:69334bd84891 183 pixel(draw_x0, draw_y0, colour);
Lerche 0:69334bd84891 184 }
Lerche 0:69334bd84891 185
Lerche 0:69334bd84891 186 if( (draw_x1 >= 0) && (draw_y1 >= 0) )
Lerche 0:69334bd84891 187 {
Lerche 0:69334bd84891 188 pixel(draw_x1, draw_y1, colour);
Lerche 0:69334bd84891 189 }
Lerche 0:69334bd84891 190
Lerche 0:69334bd84891 191 if( (draw_x2 <= OLED_DISPLAY_WIDTH) && (draw_y2 <= OLED_DISPLAY_HEIGHT) )
Lerche 0:69334bd84891 192 {
Lerche 0:69334bd84891 193 pixel(draw_x2, draw_y2, colour);
Lerche 0:69334bd84891 194 }
Lerche 0:69334bd84891 195
Lerche 0:69334bd84891 196 if( (draw_x3 >=0 ) && (draw_y3 <= OLED_DISPLAY_HEIGHT) )
Lerche 0:69334bd84891 197 {
Lerche 0:69334bd84891 198 pixel(draw_x3, draw_y3, colour);
Lerche 0:69334bd84891 199 }
Lerche 0:69334bd84891 200
Lerche 0:69334bd84891 201 if( (draw_x4 <= /*OLED_DISPLAY_HEIGHT*/OLED_DISPLAY_WIDTH) && (draw_y4 >= 0) )
Lerche 0:69334bd84891 202 {
Lerche 0:69334bd84891 203 pixel(draw_x4, draw_y4, colour);
Lerche 0:69334bd84891 204 }
Lerche 0:69334bd84891 205
Lerche 0:69334bd84891 206 if( (draw_x5 >= 0) && (draw_y5 >= 0) )
Lerche 0:69334bd84891 207 {
Lerche 0:69334bd84891 208 pixel(draw_x5, draw_y5, colour);
Lerche 0:69334bd84891 209 }
Lerche 0:69334bd84891 210 if( (draw_x6 <= OLED_DISPLAY_WIDTH) && (draw_y6 <= OLED_DISPLAY_HEIGHT) )
Lerche 0:69334bd84891 211 {
Lerche 0:69334bd84891 212 pixel(draw_x6, draw_y6, colour);
Lerche 0:69334bd84891 213 }
Lerche 0:69334bd84891 214 if( (draw_x7 >= 0) && (draw_y7 <= OLED_DISPLAY_HEIGHT) )
Lerche 0:69334bd84891 215 {
Lerche 0:69334bd84891 216 pixel(draw_x7, draw_y7, colour);
Lerche 0:69334bd84891 217 }
Lerche 0:69334bd84891 218 }
Lerche 0:69334bd84891 219 return;
Lerche 0:69334bd84891 220 }
Lerche 0:69334bd84891 221
Lerche 0:69334bd84891 222 void EAOLED::hline(int x0, int x1, int y, int colour) {
Lerche 0:69334bd84891 223 for(int x=x0; x<x1; x++){
Lerche 0:69334bd84891 224 pixel(x, y, colour);
Lerche 0:69334bd84891 225 }
Lerche 0:69334bd84891 226 return;
Lerche 0:69334bd84891 227 }
Lerche 0:69334bd84891 228
Lerche 0:69334bd84891 229 void EAOLED::vline(int y0, int y1, int x, int colour) {
Lerche 0:69334bd84891 230 for(int y=y0; y<y1; y++){
Lerche 0:69334bd84891 231 pixel(x, y, colour);
Lerche 0:69334bd84891 232 }
Lerche 0:69334bd84891 233 return;
Lerche 0:69334bd84891 234 }
Lerche 0:69334bd84891 235
Lerche 0:69334bd84891 236 void EAOLED::line(int x0, int y0, int x1, int y1, int colour) {
Lerche 0:69334bd84891 237 int dx = 0, dy = 0;
Lerche 0:69334bd84891 238 int dx_sym = 0, dy_sym = 0;
Lerche 0:69334bd84891 239 int dx_x2 = 0, dy_x2 = 0;
Lerche 0:69334bd84891 240 int di = 0;
Lerche 0:69334bd84891 241
Lerche 0:69334bd84891 242 dx = x1-x0;
Lerche 0:69334bd84891 243 dy = y1-y0;
Lerche 0:69334bd84891 244
Lerche 0:69334bd84891 245
Lerche 0:69334bd84891 246 if(dx == 0) /* vertical line */
Lerche 0:69334bd84891 247 {
Lerche 0:69334bd84891 248 for(int y=y0; y<y1; y++){
Lerche 0:69334bd84891 249 pixel(x0, y, colour);
Lerche 0:69334bd84891 250 }
Lerche 0:69334bd84891 251 return;
Lerche 0:69334bd84891 252 }
Lerche 0:69334bd84891 253
Lerche 0:69334bd84891 254 if(dx > 0)
Lerche 0:69334bd84891 255 {
Lerche 0:69334bd84891 256 dx_sym = 1;
Lerche 0:69334bd84891 257 }
Lerche 0:69334bd84891 258 else
Lerche 0:69334bd84891 259 {
Lerche 0:69334bd84891 260 dx_sym = -1;
Lerche 0:69334bd84891 261 }
Lerche 0:69334bd84891 262
Lerche 0:69334bd84891 263
Lerche 0:69334bd84891 264 if(dy == 0) /* horizontal line */
Lerche 0:69334bd84891 265 {
Lerche 0:69334bd84891 266 for(int x=x0; x<x1; x++){
Lerche 0:69334bd84891 267 pixel(x, y0, colour);
Lerche 0:69334bd84891 268 }
Lerche 0:69334bd84891 269 return;
Lerche 0:69334bd84891 270 }
Lerche 0:69334bd84891 271
Lerche 0:69334bd84891 272
Lerche 0:69334bd84891 273 if(dy > 0)
Lerche 0:69334bd84891 274 {
Lerche 0:69334bd84891 275 dy_sym = 1;
Lerche 0:69334bd84891 276 }
Lerche 0:69334bd84891 277 else
Lerche 0:69334bd84891 278 {
Lerche 0:69334bd84891 279 dy_sym = -1;
Lerche 0:69334bd84891 280 }
Lerche 0:69334bd84891 281
Lerche 0:69334bd84891 282 dx = dx_sym*dx;
Lerche 0:69334bd84891 283 dy = dy_sym*dy;
Lerche 0:69334bd84891 284
Lerche 0:69334bd84891 285 dx_x2 = dx*2;
Lerche 0:69334bd84891 286 dy_x2 = dy*2;
Lerche 0:69334bd84891 287
Lerche 0:69334bd84891 288 if(dx >= dy)
Lerche 0:69334bd84891 289 {
Lerche 0:69334bd84891 290 di = dy_x2 - dx;
Lerche 0:69334bd84891 291 while(x0 != x1)
Lerche 0:69334bd84891 292 {
Lerche 0:69334bd84891 293
Lerche 0:69334bd84891 294 pixel(x0, y0, colour);
Lerche 0:69334bd84891 295 x0 += dx_sym;
Lerche 0:69334bd84891 296 if(di<0)
Lerche 0:69334bd84891 297 {
Lerche 0:69334bd84891 298 di += dy_x2;
Lerche 0:69334bd84891 299 }
Lerche 0:69334bd84891 300 else
Lerche 0:69334bd84891 301 {
Lerche 0:69334bd84891 302 di += dy_x2 - dx_x2;
Lerche 0:69334bd84891 303 y0 += dy_sym;
Lerche 0:69334bd84891 304 }
Lerche 0:69334bd84891 305 }
Lerche 0:69334bd84891 306 pixel(x0, y0, colour);
Lerche 0:69334bd84891 307 }
Lerche 0:69334bd84891 308 else
Lerche 0:69334bd84891 309 {
Lerche 0:69334bd84891 310 di = dx_x2 - dy;
Lerche 0:69334bd84891 311 while(y0 != y1)
Lerche 0:69334bd84891 312 {
Lerche 0:69334bd84891 313 pixel(x0, y0, colour);
Lerche 0:69334bd84891 314 y0 += dy_sym;
Lerche 0:69334bd84891 315 if(di < 0)
Lerche 0:69334bd84891 316 {
Lerche 0:69334bd84891 317 di += dx_x2;
Lerche 0:69334bd84891 318 }
Lerche 0:69334bd84891 319 else
Lerche 0:69334bd84891 320 {
Lerche 0:69334bd84891 321 di += dx_x2 - dy_x2;
Lerche 0:69334bd84891 322 x0 += dx_sym;
Lerche 0:69334bd84891 323 }
Lerche 0:69334bd84891 324 }
Lerche 0:69334bd84891 325 pixel(x0, y0, colour);
Lerche 0:69334bd84891 326 }
Lerche 0:69334bd84891 327 return;
Lerche 0:69334bd84891 328 }
Lerche 0:69334bd84891 329
Lerche 0:69334bd84891 330 void EAOLED::rect(int x0, int y0, int x1, int y1, int colour) {
Lerche 0:69334bd84891 331
Lerche 0:69334bd84891 332 for(int x=x0; x<x1; x++){
Lerche 0:69334bd84891 333 pixel(x, y0, colour);
Lerche 0:69334bd84891 334 }
Lerche 0:69334bd84891 335 for(int x=x0; x<x1; x++){
Lerche 0:69334bd84891 336 pixel(x, y1, colour);
Lerche 0:69334bd84891 337 }
Lerche 0:69334bd84891 338 for(int y=y0; y<y1; y++){
Lerche 0:69334bd84891 339 pixel(x0, y, colour);
Lerche 0:69334bd84891 340 }
Lerche 0:69334bd84891 341 for(int y=y0; y<y1; y++){
Lerche 0:69334bd84891 342 pixel(x1, y, colour);
Lerche 0:69334bd84891 343 }
Lerche 0:69334bd84891 344 return;
Lerche 0:69334bd84891 345 }
Lerche 0:69334bd84891 346
Lerche 0:69334bd84891 347 void EAOLED::fillrect(int x0, int y0, int x1, int y1, int colour) {
Lerche 0:69334bd84891 348
Lerche 0:69334bd84891 349 int i = 0;
Lerche 0:69334bd84891 350
Lerche 0:69334bd84891 351 if(x0 > x1)
Lerche 0:69334bd84891 352 {
Lerche 0:69334bd84891 353 i = x0;
Lerche 0:69334bd84891 354 x0 = x1;
Lerche 0:69334bd84891 355 x1 = i;
Lerche 0:69334bd84891 356 }
Lerche 0:69334bd84891 357
Lerche 0:69334bd84891 358 if(y0 > y1)
Lerche 0:69334bd84891 359 {
Lerche 0:69334bd84891 360 i = y0;
Lerche 0:69334bd84891 361 y0 = y1;
Lerche 0:69334bd84891 362 y1 = i;
Lerche 0:69334bd84891 363 }
Lerche 0:69334bd84891 364
Lerche 0:69334bd84891 365 if(y0 == y1)
Lerche 0:69334bd84891 366 {
Lerche 0:69334bd84891 367 for(int x=x0; x<x1; x++){
Lerche 0:69334bd84891 368 pixel(x, y0, colour);
Lerche 0:69334bd84891 369 }
Lerche 0:69334bd84891 370 return;
Lerche 0:69334bd84891 371 }
Lerche 0:69334bd84891 372
Lerche 0:69334bd84891 373 if(x0 == x1)
Lerche 0:69334bd84891 374 {
Lerche 0:69334bd84891 375 for(int y=y0; y<y1; y++){
Lerche 0:69334bd84891 376 pixel(x0, y, colour);
Lerche 0:69334bd84891 377 }
Lerche 0:69334bd84891 378 return;
Lerche 0:69334bd84891 379 }
Lerche 0:69334bd84891 380
Lerche 0:69334bd84891 381 while(y0 <= y1)
Lerche 0:69334bd84891 382 {
Lerche 0:69334bd84891 383 for(int x=x0; x<x1; x++){
Lerche 0:69334bd84891 384 pixel(x, y0, colour);
Lerche 0:69334bd84891 385 }
Lerche 0:69334bd84891 386 y0++;
Lerche 0:69334bd84891 387 }
Lerche 0:69334bd84891 388 return;
Lerche 0:69334bd84891 389
Lerche 0:69334bd84891 390 }