Christian Lerche
/
EAOLED
EA OLED (Orig. by SFord, retouched by Lerche)
EAOLED.cpp
- Committer:
- Lerche
- Date:
- 2010-10-03
- Revision:
- 0:69334bd84891
File content as of revision 0:69334bd84891:
// test library for Embedded Artists OLED used on Xpresso Baseboard #include "EAOLED.h" #include "mbed.h" EAOLED::EAOLED(PinName mosi, PinName dnc, PinName sclk, PinName cs, PinName power) : _spi(mosi, NC, sclk), _data(dnc), _cs(cs), _power(power) { reset(); } void EAOLED::command(int value) { _data = 0; _cs = 0; _spi.write(value); _cs = 1; } void EAOLED::data(int value) { _data = 1; _cs = 0; _spi.write(value); _cs = 1; } void EAOLED::reset() { _power = 0; _cs = 1; // Startup sequence recommended by embedded artists baseboard reference code command(0x02); // set low column address command(0x12); // set high column address command(0x40); // display start set command(0x2e); // stop horzontal scroll command(0x81); // set contrast control register command(0x32); // command(0x82); // brightness for color banks command(0x80); // display on command(0xa1); // set segment re-map command(0xa6); // set normal/inverse display command(0xa8); // set multiplex ratio command(0x3F); // command(0xd3); // set display offset command(0x40); // command(0xad); // set dc-dc on/off command(0x8E); // command(0xc8); // set com output scan direction command(0xd5); // set display clock divide ratio/oscillator/frequency command(0xf0); // command(0xd8); // set area color mode on/off & low power display mode command(0x05); // command(0xd9); // set pre-charge period command(0xF1); // command(0xda); // set com pins hardware configuration command(0x12); // command(0xdb); // set vcom deselect level command(0x34); // command(0x91); // set look up table for area color command(0x3f); // command(0x3f); // command(0x3f); // command(0x3f); // command(0xaf); // display on command(0xa4); // display on wait_us(10); _power = 1; } #define OLED_DISPLAY_WIDTH 96 #define OLED_DISPLAY_HEIGHT 64 void EAOLED::pixel(int x, int y, int colour) { int page = y >> 3; int address = 18 + x; int lo = (address >> 0) & 0x0F; int hi = (address >> 4) | 0x10; int mask = 1 << (y & 0x7); int byte = page * OLED_DISPLAY_WIDTH + x; if(colour) { framebuffer[byte] |= mask; } else { framebuffer[byte] &= ~mask; } command(0xB0 + page); command(lo); command(hi); data(framebuffer[byte]); } void EAOLED::circle(int x0, int y0, int r, int colour) { #define OLED_DISPLAY_WIDTH 96 #define OLED_DISPLAY_HEIGHT 64 int draw_x0, draw_y0; int draw_x1, draw_y1; int draw_x2, draw_y2; int draw_x3, draw_y3; int draw_x4, draw_y4; int draw_x5, draw_y5; int draw_x6, draw_y6; int draw_x7, draw_y7; int xx, yy; int di; if(r == 0) /* no radius */ { return; } draw_x0 = draw_x1 = x0; draw_y0 = draw_y1 = y0 + r; if(draw_y0 < OLED_DISPLAY_HEIGHT) { pixel(draw_x0, draw_y0, colour); /* 90 degree */ } draw_x2 = draw_x3 = x0; draw_y2 = draw_y3 = y0 - r; if(draw_y2 >= 0) { pixel(draw_x2, draw_y2, colour); /* 270 degree */ } draw_x4 = draw_x6 = x0 + r; draw_y4 = draw_y6 = y0; if(draw_x4 < OLED_DISPLAY_WIDTH) { pixel(draw_x4, draw_y4, colour); /* 0 degree */ } draw_x5 = draw_x7 = x0 - r; draw_y5 = draw_y7 = y0; if(draw_x5>=0) { pixel(draw_x5, draw_y5, colour); /* 180 degree */ } if(r == 1) { return; } di = 3 - 2*r; xx = 0; yy = r; while(xx < yy) { if(di < 0) { di += 4*xx + 6; } else { di += 4*(xx - yy) + 10; yy--; draw_y0--; draw_y1--; draw_y2++; draw_y3++; draw_x4--; draw_x5++; draw_x6--; draw_x7++; } xx++; draw_x0++; draw_x1--; draw_x2++; draw_x3--; draw_y4++; draw_y5++; draw_y6--; draw_y7--; if( (draw_x0 <= OLED_DISPLAY_WIDTH) && (draw_y0>=0) ) { pixel(draw_x0, draw_y0, colour); } if( (draw_x1 >= 0) && (draw_y1 >= 0) ) { pixel(draw_x1, draw_y1, colour); } if( (draw_x2 <= OLED_DISPLAY_WIDTH) && (draw_y2 <= OLED_DISPLAY_HEIGHT) ) { pixel(draw_x2, draw_y2, colour); } if( (draw_x3 >=0 ) && (draw_y3 <= OLED_DISPLAY_HEIGHT) ) { pixel(draw_x3, draw_y3, colour); } if( (draw_x4 <= /*OLED_DISPLAY_HEIGHT*/OLED_DISPLAY_WIDTH) && (draw_y4 >= 0) ) { pixel(draw_x4, draw_y4, colour); } if( (draw_x5 >= 0) && (draw_y5 >= 0) ) { pixel(draw_x5, draw_y5, colour); } if( (draw_x6 <= OLED_DISPLAY_WIDTH) && (draw_y6 <= OLED_DISPLAY_HEIGHT) ) { pixel(draw_x6, draw_y6, colour); } if( (draw_x7 >= 0) && (draw_y7 <= OLED_DISPLAY_HEIGHT) ) { pixel(draw_x7, draw_y7, colour); } } return; } void EAOLED::hline(int x0, int x1, int y, int colour) { for(int x=x0; x<x1; x++){ pixel(x, y, colour); } return; } void EAOLED::vline(int y0, int y1, int x, int colour) { for(int y=y0; y<y1; y++){ pixel(x, y, colour); } return; } void EAOLED::line(int x0, int y0, int x1, int y1, int colour) { int dx = 0, dy = 0; int dx_sym = 0, dy_sym = 0; int dx_x2 = 0, dy_x2 = 0; int di = 0; dx = x1-x0; dy = y1-y0; if(dx == 0) /* vertical line */ { for(int y=y0; y<y1; y++){ pixel(x0, y, colour); } return; } if(dx > 0) { dx_sym = 1; } else { dx_sym = -1; } if(dy == 0) /* horizontal line */ { for(int x=x0; x<x1; x++){ pixel(x, y0, colour); } return; } if(dy > 0) { dy_sym = 1; } else { dy_sym = -1; } dx = dx_sym*dx; dy = dy_sym*dy; dx_x2 = dx*2; dy_x2 = dy*2; if(dx >= dy) { di = dy_x2 - dx; while(x0 != x1) { pixel(x0, y0, colour); x0 += dx_sym; if(di<0) { di += dy_x2; } else { di += dy_x2 - dx_x2; y0 += dy_sym; } } pixel(x0, y0, colour); } else { di = dx_x2 - dy; while(y0 != y1) { pixel(x0, y0, colour); y0 += dy_sym; if(di < 0) { di += dx_x2; } else { di += dx_x2 - dy_x2; x0 += dx_sym; } } pixel(x0, y0, colour); } return; } void EAOLED::rect(int x0, int y0, int x1, int y1, int colour) { for(int x=x0; x<x1; x++){ pixel(x, y0, colour); } for(int x=x0; x<x1; x++){ pixel(x, y1, colour); } for(int y=y0; y<y1; y++){ pixel(x0, y, colour); } for(int y=y0; y<y1; y++){ pixel(x1, y, colour); } return; } void EAOLED::fillrect(int x0, int y0, int x1, int y1, int colour) { int i = 0; if(x0 > x1) { i = x0; x0 = x1; x1 = i; } if(y0 > y1) { i = y0; y0 = y1; y1 = i; } if(y0 == y1) { for(int x=x0; x<x1; x++){ pixel(x, y0, colour); } return; } if(x0 == x1) { for(int y=y0; y<y1; y++){ pixel(x0, y, colour); } return; } while(y0 <= y1) { for(int x=x0; x<x1; x++){ pixel(x, y0, colour); } y0++; } return; }