This is the code used on my video series "Hybrid Supercapacitor Car Battery" for my own hardware monitoring system. THe videos can be found on madelectronengineering.com

Dependencies:   BurstSPI Fonts INA219 mbed LPC1114_WakeInterruptIn

Fork of SharpMemoryLCD by Paul Staron

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SharpLCD.cpp Source File

SharpLCD.cpp

00001 
00002 #include "mbed.h"
00003 #include "SharpLCD.h"
00004 
00005 const unsigned char FONT8x8[97][8] = {
00006 {0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, num_bytes_per_char
00007 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space 0x20
00008 {0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00}, // !
00009 {0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // "
00010 {0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00}, // #
00011 {0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00}, // $
00012 {0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00}, // %
00013 {0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00}, // &
00014 {0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00}, // '
00015 {0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, // (
00016 {0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, // )
00017 {0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00}, // *
00018 {0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00}, // +
00019 {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // ,
00020 {0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, // -
00021 {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // .
00022 {0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00}, // / (forward slash)
00023 {0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00}, // 0 0x30
00024 {0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00}, // 1
00025 {0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00}, // 2
00026 {0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 3
00027 {0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00}, // 4
00028 {0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 5
00029 {0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, // 6
00030 {0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00}, // 7
00031 {0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 8
00032 {0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 9
00033 {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // :
00034 {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30}, // ;
00035 {0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, // <
00036 {0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00}, // =
00037 {0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, // >
00038 {0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00}, // ?
00039 {0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00}, // @ 0x40
00040 {0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00}, // A
00041 {0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00}, // B
00042 {0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00}, // C
00043 {0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00}, // D
00044 {0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00}, // E
00045 {0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00}, // F
00046 {0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00}, // G
00047 {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, // H
00048 {0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // I
00049 {0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00}, // J
00050 {0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00}, // K
00051 {0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00}, // L
00052 {0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00}, // M
00053 {0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00}, // N
00054 {0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00}, // O
00055 {0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00}, // P 0x50
00056 {0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00}, // Q
00057 {0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00}, // R
00058 {0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00}, // S
00059 {0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00}, // T
00060 {0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00}, // U
00061 {0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, // V
00062 {0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}, // W
00063 {0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00}, // X
00064 {0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00}, // Y
00065 {0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00}, // Z
00066 {0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00}, // [
00067 {0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // \ (back slash)
00068 {0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00}, // ]
00069 {0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // ^
00070 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, // _
00071 {0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}, // ` 0x60
00072 {0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00}, // a
00073 {0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00}, // b
00074 {0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, // c
00075 {0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00}, // d
00076 {0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, // e
00077 {0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00}, // f
00078 {0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C}, // g
00079 {0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00}, // h
00080 {0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, // i
00081 {0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C}, // j
00082 {0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00}, // k
00083 {0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // l
00084 {0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00}, // m
00085 {0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, // n
00086 {0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, // o
00087 {0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78}, // p
00088 {0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F}, // q
00089 {0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00}, // r
00090 {0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, // s
00091 {0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00}, // t
00092 {0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00}, // u
00093 {0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, // v
00094 {0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00}, // w
00095 {0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00}, // x
00096 {0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C}, // y
00097 {0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00}, // z
00098 {0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00}, // {
00099 {0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00}, // |
00100 {0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00}, // }
00101 {0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
00102 {0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00}}; // DEL
00103 
00104 // SharpLCD commands
00105 #define SharpLCD_CMD_UPDATE     (0x01)
00106 #define SharpLCD_CMD_ALL_CLEAR  (0x04)
00107 
00108 // Macro to switch endianness on char value
00109 #define SWAP8(a) ((((a) & 0x80) >> 7) | (((a) & 0x40) >> 5) | (((a) & 0x20) >> 3) | (((a) & 0x10) >> 1) | (((a) & 0x08) << 1) | (((a) & 0x04) << 3) | (((a) & 0x02) << 5) | (((a) & 0x01) << 7))
00110 
00111 SharpLCD::SharpLCD(PinName mosi, PinName miso, PinName sclk, PinName chipSelect, PinName enable, PinName extcom)
00112          :  spi(mosi, miso, sclk), chipSelect(chipSelect), Enable(enable), ExtCom(extcom)
00113 {
00114     //Initialize
00115     spi.frequency(1000000);// Nominal speed is 1MHz, tested working at 3MHz
00116     lcdPolarity = 0;    
00117     rowCount = 0;
00118     memset((uint8_t*)pixelBuffer, White, sizeof(pixelBuffer));  // init full pixel buffer to White
00119     memset((void*)RowState, 0, sizeof(RowState));   // init row status
00120     // current pixel location
00121     _x = 0;
00122     _y = 0;
00123     // window settings
00124     _x1 = 0;
00125     _x2 = 0;
00126     _y1 = 0;
00127     _y2 = 0;
00128      _row = 0;
00129     _column = 0;
00130 }
00131 // Call this function at 55 ~ 65 Hz to keep the display up-to-date.
00132 void SharpLCD::toggle() {
00133     ExtCom=!ExtCom;
00134 }
00135 
00136 void SharpLCD::enableDisplay(void) {
00137     Enable = 1;
00138 }
00139 
00140 void SharpLCD::disableDisplay(void) {
00141     Enable = 0;
00142 }
00143 
00144 void SharpLCD::clearspace() {
00145     // set pixel buffer to zero but do not blank screen
00146     memset((void*)pixelBuffer, foreground, sizeof(pixelBuffer));
00147     memset((void*)RowState, 0, sizeof(RowState));
00148     }
00149 
00150 void SharpLCD::clearImmediate() {
00151     // Clear out the pixel buffer
00152     memset((void*)pixelBuffer, foreground, sizeof(pixelBuffer));
00153     memset((void*)RowState, 0, sizeof(RowState));
00154     chipSelect = 1;
00155     // send clear command to display
00156     cmd[0] = (uint8_t)(SWAP8(SharpLCD_CMD_ALL_CLEAR | lcdPolarity));
00157     cmd[1] = 0; 
00158     spi.fastWrite(cmd[0]);
00159     spi.fastWrite(cmd[1]);
00160     spi.clearRX();  
00161     chipSelect = 0;
00162 }
00163 
00164 void SharpLCD::update() {
00165     //Initialize the command vector
00166     cmd[0] = (uint8_t)SWAP8(SharpLCD_CMD_UPDATE);
00167     cmd[1] = SWAP8(1);
00168     chipSelect=1;
00169     rowCount = 0;
00170     display_write();
00171 }
00172 
00173 void SharpLCD::display_write() {    
00174     while(rowCount < DISPLAY_HEIGHT) {      
00175         // Determine the next line to send
00176         if((RowState[rowCount / DISPLAY_BUFFER_TYPE_SIZE] & (1 << (rowCount % DISPLAY_BUFFER_TYPE_SIZE))) != 0) {
00177             // Row has pixel changes, send this row to the display
00178             cmd[1] = (uint8_t)SWAP8(rowCount+1);
00179             
00180             memcpy(&(cmd[2]), (const void*)&(pixelBuffer[rowCount*(DISPLAY_WIDTH/DISPLAY_BUFFER_TYPE_SIZE)]), DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE));
00181                         
00182             int len=sizeof(cmd);            
00183             for(int i=0; i<len; i++) {      
00184                 spi.fastWrite(cmd[i]);      
00185                 }
00186             // update pixel change status of this line as sent
00187             RowState[rowCount / DISPLAY_BUFFER_TYPE_SIZE] &= ~(1 << (rowCount % DISPLAY_BUFFER_TYPE_SIZE));             
00188         }               
00189         rowCount++;
00190     }
00191     // send end of transfer bytes 
00192     spi.fastWrite(cmd[0]);
00193     spi.fastWrite(0xFF);
00194     // clear SPI RX buffer
00195     spi.clearRX();                  
00196     chipSelect = 0;     
00197 }
00198 
00199 void SharpLCD::pixel(int x, int y, int colour) {
00200     uint8_t swapx = 7 - ((unsigned int)x & 0x07);
00201         x = ((unsigned int)x & 0xFFFFFFF8) | swapx;
00202         // determine if row has pixel changes
00203         bool change = ((pixelBuffer[((y * DISPLAY_WIDTH) + x) / DISPLAY_BUFFER_TYPE_SIZE] & (1 << (x % DISPLAY_BUFFER_TYPE_SIZE))) != ((colour & 0x01) << (x % DISPLAY_BUFFER_TYPE_SIZE)));
00204         if(change) {
00205             // xor operation
00206             pixelBuffer[((y * DISPLAY_WIDTH) + x) / DISPLAY_BUFFER_TYPE_SIZE] ^= (1 << (x % DISPLAY_BUFFER_TYPE_SIZE));
00207             // update pixel change status of this line
00208             RowState[y / DISPLAY_BUFFER_TYPE_SIZE] |= (1 << (y % DISPLAY_BUFFER_TYPE_SIZE));
00209         }
00210     }
00211     
00212 int SharpLCD::_putc(int value) {
00213     if(value == '\n') {
00214         _column = 0;
00215         _row++;
00216         if(_row >= rows()) {
00217             _row = 0;
00218         }
00219     } else {
00220         character(_column, _row, value);
00221         _column++;
00222         if(_column >= columns()) {
00223             _column = 0;
00224             _row++;
00225             if(_row >= rows()) {
00226                 _row = 0;
00227             }
00228         }
00229     }
00230     return value;
00231 }
00232 
00233 void SharpLCD::set_font(const unsigned char * f) {
00234     font = f;
00235     if (font==NULL){externalfont=0;}    // set display.font
00236         else{externalfont=1;}
00237 }
00238 
00239 void SharpLCD::locate(int column, int row) {
00240     _column = column;
00241     _row = row;
00242     char_x = column;
00243     char_y = row;
00244 }
00245 
00246 int SharpLCD::_getc() {
00247     return -1;
00248 }
00249 
00250 void SharpLCD::printf(const char* format, ...) {
00251     char buffer[MAX_PRINTF_CHARS + 1] = { 0 };
00252     uint32_t iterator = 0;
00253     va_list args;
00254     va_start(args, format);
00255     vsprintf(buffer, format, args);
00256     va_end(args);
00257 
00258     while((buffer[iterator] != 0) && (iterator < MAX_PRINTF_CHARS)) {
00259         _putc(buffer[iterator++]);
00260     }
00261 }
00262    
00263 void SharpLCD::character(int column, int row, int value) {    
00264     if(externalfont){ // send external font
00265         unsigned int hor,vert,offset,bpl,j,i,b;
00266         const unsigned char* sign;
00267         unsigned char z,w;
00268         if ((value < 31) || (value > 127)) return;   // test char range
00269         // read font parameter from start of array
00270         offset = font[0];                    // bytes / char
00271         hor = font[1];                       // get hor size of font
00272         vert = font[2];                      // get vert size of font
00273         bpl = font[3];                       // bytes per line
00274         if (char_x + hor > width()) {
00275             char_x = 0;
00276             char_y = char_y + vert;
00277             if (char_y >= height() - font[2]) {
00278                 char_y = 0;
00279             }
00280         }     
00281         window(char_x, char_y,hor,vert); 
00282         sign = &font[((value -32) * offset) + 4]; 
00283         w = sign[0];                         
00284         for (j=0; j<vert; j++) {  
00285             for (i=0; i<hor; i++) {  
00286                 z =  sign[bpl * i + ((j & 0xF8) >> 3)+1];
00287                 b = 1 << (j & 0x07);
00288                 if (( z & b ) == 0x00) {               
00289                     putp(foreground);              
00290                 } 
00291                 else {                     
00292                     putp(background);                                
00293                 }
00294             }
00295         }
00296         if ((w + 2) < hor) {                   // x offset to next char
00297             char_x += w + 2;
00298             }
00299             else char_x += hor;
00300     }   
00301     // send default font using blitbit function             
00302     else{
00303         blitbit(column * 8, row * 8, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
00304         }
00305 }
00306 
00307 void SharpLCD::window(int x, int y, int w, int h) {
00308     // current pixel location
00309     _x = x;
00310     _y = y;
00311     // window settings
00312     _x1 = x;
00313     _x2 = x + w - 1;
00314     _y1 = y;
00315     _y2 = y + h - 1;
00316 }
00317     
00318 void SharpLCD::putp(int colour) {
00319     pixel(_x, _y, colour);
00320     _x++;
00321     if(_x > _x2) {
00322         _x = _x1;
00323         _y++;
00324         if(_y > _y2) {
00325             _y = _y1;
00326         }
00327     }
00328 }
00329 
00330 void SharpLCD::rect(int x0, int y0, int x1, int y1, int color) {
00331     if (x1 > x0) hline(x0,x1,y0,color);
00332     else  hline(x1,x0,y0,color);
00333     if (y1 > y0) vline(x0,y0,y1,color);
00334     else vline(x0,y1,y0,color);
00335     if (x1 > x0) hline(x0,x1,y1,color);
00336     else  hline(x1,x0,y1,color);
00337     if (y1 > y0) vline(x1,y0,y1,color);
00338     else vline(x1,y1,y0,color);
00339     return;
00340 }
00341 
00342 void SharpLCD::fillrect(int x0, int y0, int w, int h, int colour) {
00343     unsigned long int index=0;
00344     if (w < 0) {
00345         x0 = x0 + w;
00346         w = -w;
00347     }
00348     if (h < 0) {
00349         y0 = y0 + h;
00350         h = -h;
00351     }
00352     window(x0,y0,w,h);
00353     int num = h*w;
00354     for( index = 0; index<num; index++ ) {
00355        putp(colour); 
00356     }
00357     return;
00358 }
00359 
00360 void SharpLCD::circle(int x, int y, int r,int colour){
00361     int ce = -r;
00362     int cx = r;
00363     int cy = 0;
00364     while(cx >= cy){
00365         pixel(x+cx,y+cy,colour);
00366         pixel(x-cx,y-cy,colour);
00367         pixel(x-cx,y+cy,colour);
00368         pixel(x+cx,y-cy,colour);
00369         pixel(x+cy,y+cx,colour);
00370         pixel(x-cy,y+cx,colour);
00371         pixel(x-cy,y-cx,colour);
00372         pixel(x+cy,y-cx,colour);
00373         ce += 2*cy++ + 1;
00374         if(ce >= 0){
00375             ce -= 2*cx---1; 
00376         }       
00377     }
00378 }
00379 
00380 void SharpLCD::ellipse(int xc, int yc, int a, int b, unsigned int colour)
00381 {
00382     int x = 0, y = b;
00383     long a2 = (long)a*a, b2 = (long)b*b;
00384     long crit1 = -(a2/4 + a%2 + b2);
00385     long crit2 = -(b2/4 + b%2 + a2);
00386     long crit3 = -(b2/4 + b%2);
00387     long t = -a2*y;
00388     long dxt = 2*b2*x, dyt = -2*a2*y;
00389     long d2xt = 2*b2, d2yt = 2*a2;
00390     while (y>=0 && x<=a) {
00391         pixel(xc+x, yc+y, colour);
00392         if (x!=0 || y!=0)
00393             pixel(xc-x, yc-y, colour);
00394         if (x!=0 && y!=0) {
00395             pixel(xc+x, yc-y, colour);
00396             pixel(xc-x, yc+y, colour);
00397         }
00398         if (t + b2*x <= crit1 ||            
00399                 t + a2*y <= crit3)          
00400             incx();
00401         else if (t - a2*y > crit2)          
00402             incy();
00403         else {
00404             incx();
00405             incy();
00406         }
00407     }
00408 }
00409 
00410 void SharpLCD::fillellipse(int xc, int yc, int a, int b, unsigned int colour)
00411 {
00412     int x = 0, y = b;
00413     int rx = x, ry = y;
00414     unsigned int width = 1;
00415     unsigned int height = 1;
00416     long a2 = (long)a*a, b2 = (long)b*b;
00417     long crit1 = -(a2/4 + a%2 + b2);
00418     long crit2 = -(b2/4 + b%2 + a2);
00419     long crit3 = -(b2/4 + b%2);
00420     long t = -a2*y;                         
00421     long dxt = 2*b2*x, dyt = -2*a2*y;
00422     long d2xt = 2*b2, d2yt = 2*a2;
00423     if (b == 0) {
00424         fillrect(xc-a, yc, 2*a+1, 1, colour);
00425         return;
00426     }
00427     while (y>=0 && x<=a) {
00428         if (t + b2*x <= crit1 ||            
00429                 t + a2*y <= crit3) {        
00430             if (height == 1)
00431                 ;                           
00432             else if (ry*2+1 > (height-1)*2) {
00433                 fillrect(xc-rx, yc-ry, width, height-1, colour);
00434                 fillrect(xc-rx, yc+ry+1, width, 1-height, colour);
00435                 ry -= height-1;
00436                 height = 1;
00437             } else {
00438                 fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
00439                 ry -= ry;
00440                 height = 1;
00441             }
00442             incx();
00443             rx++;
00444             width += 2;
00445         } else if (t - a2*y > crit2) {      
00446             incy();
00447             height++;
00448         } else {
00449             if (ry*2+1 > height*2) {
00450                 fillrect(xc-rx, yc-ry, width, height, colour);
00451                 fillrect(xc-rx, yc+ry+1, width, -height, colour);
00452             } else {
00453                 fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
00454             }
00455             incx();
00456             incy();
00457             rx++;
00458             width += 2;
00459             ry -= height;
00460             height = 1;
00461         }
00462     }
00463     if (ry > height) {
00464         fillrect(xc-rx, yc-ry, width, height, colour);
00465         fillrect(xc-rx, yc+ry+1, width, -height, colour);
00466     } else {
00467         fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
00468     }
00469 }
00470 
00471 void SharpLCD::line(int x0, int y0, int x1, int y1, int colour) {
00472     int   dx = 0, dy = 0;
00473     int   dx_sym = 0, dy_sym = 0;
00474     int   dx_x2 = 0, dy_x2 = 0;
00475     int   di = 0;
00476     dx = x1-x0;
00477     dy = y1-y0;
00478 
00479     if (dx == 0) {        
00480         if (y1 > y0) vline(x0,y0,y1,colour);
00481         else vline(x0,y1,y0,colour);
00482         return;
00483     }
00484     if (dx > 0) {
00485         dx_sym = 1;
00486     } else {
00487         dx_sym = -1;
00488     }
00489     if (dy == 0) {        
00490         if (x1 > x0) hline(x0,x1,y0,colour);
00491         else  hline(x1,x0,y0,colour);
00492         return;
00493     }
00494     if (dy > 0) {
00495         dy_sym = 1;
00496     } else {
00497         dy_sym = -1;
00498     }
00499     dx = dx_sym*dx;
00500     dy = dy_sym*dy;
00501     dx_x2 = dx*2;
00502     dy_x2 = dy*2;
00503     if (dx >= dy) {
00504         di = dy_x2 - dx;
00505         while (x0 != x1) {
00506 
00507             pixel(x0, y0, colour);
00508             x0 += dx_sym;
00509             if (di<0) {
00510                 di += dy_x2;
00511             } else {
00512                 di += dy_x2 - dx_x2;
00513                 y0 += dy_sym;
00514             }
00515         }
00516         pixel(x0, y0, colour);
00517     } else {
00518         di = dx_x2 - dy;
00519         while (y0 != y1) {
00520             pixel(x0, y0, colour);
00521             y0 += dy_sym;
00522             if (di < 0) {
00523                 di += dx_x2;
00524             } else {
00525                 di += dx_x2 - dy_x2;
00526                 x0 += dx_sym;
00527             }
00528         }
00529         pixel(x0, y0, colour);
00530     }
00531     return;
00532 }
00533 
00534 void SharpLCD::hline(int x0, int x1, int y, int colour) {
00535     int w;
00536     w = x1 - x0 + 1;
00537     window(x0,y,w,1);
00538     for (int x=0; x<w; x++) {
00539         putp(colour);
00540     }
00541     return;
00542 }
00543 
00544 void SharpLCD::vline(int x, int y0, int y1, int colour) {
00545     int h;
00546     h = y1 - y0 + 1;
00547     window(x,y0,1,h);
00548     for (int y=0; y<h; y++) {
00549         putp(colour);
00550     }
00551     return;
00552 }
00553     
00554 void SharpLCD::blit(int x, int y, int w, int h, const int *colour) { 
00555     window(x, y, w, h);
00556     for(int i=0; i<w*h; i++) {
00557         putp(colour[i]);
00558     }
00559 }
00560     
00561 void SharpLCD::blitbit(int x, int y, int w, int h, const char* colour) {
00562     window(x, y, w, h);
00563     for(int i = 0; i < w*h; i++) {
00564         char byte = colour[i >> 3];
00565         int offset = i & 0x7;
00566         int c = ((byte << (offset)) & 0x80) ? background : foreground;
00567         putp(c);
00568     }
00569 }
00570     
00571 int SharpLCD::columns() { 
00572     return width() / 8; 
00573 }
00574 
00575 int SharpLCD::rows() { 
00576     return height() / 8; 
00577 }
00578 
00579 int SharpLCD::width() {
00580     return DISPLAY_WIDTH;
00581 }
00582 
00583 int SharpLCD::height() {
00584     return DISPLAY_HEIGHT;
00585 }
00586 
00587 void SharpLCD::showBMP(const uint8_t* bitmap, const uint32_t bmpWidth, const uint32_t bmpHeight, const uint32_t startX, const uint32_t startY) {
00588     uint32_t bitmapLine = 0, y = startY, bytesPerLine = ((bmpWidth >= (DISPLAY_WIDTH - startX)) ? (DISPLAY_WIDTH - startX) : bmpWidth) / 8;
00589 
00590     // Apply constraints
00591     if((bmpWidth & 0x07) != 0) return;
00592     if(startX >= DISPLAY_WIDTH) return;
00593     
00594     // Copy over bytes to pixel buffer
00595     for(; y < startY + bmpHeight; y++) {
00596         memcpy( (void*) &(((uint8_t*)pixelBuffer)[((y * DISPLAY_WIDTH) + startX) / 8]),
00597                 (const void*) &(bitmap[bitmapLine * (bmpWidth / 8)]),
00598                 bytesPerLine);
00599         RowState[y / DISPLAY_BUFFER_TYPE_SIZE] |= (1 << (y % DISPLAY_BUFFER_TYPE_SIZE));
00600         bitmapLine++;
00601     }
00602     return;
00603 }
00604