k og / HD66766
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HD66766.cpp Source File

HD66766.cpp

00001 #include "HD66766.h"
00002 #include "glcdfont.h"
00003 
00004 HD66766::HD66766(
00005     PinName rd, PinName wr, PinName rs, PinName cs, PinName rst,
00006     PinName d0, PinName d1, PinName d2, PinName d3,
00007     PinName d4, PinName d5, PinName d6, PinName d7,
00008     PinName d8, PinName d9, PinName d10, PinName d11,
00009     PinName d12, PinName d13, PinName d14, PinName d15
00010     ):
00011     _rd(rd), _wr(wr), _rs(rs), _cs(cs), _rst(rst),
00012     _d(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15)
00013 {
00014     _width = LCDWIDTH;
00015     _height = LCDHEIGHT;
00016     
00017     _rd=1; 
00018     _wr=1;
00019     _rs=1;
00020     _cs=1;
00021     _rst = 1;
00022 
00023     cursor_y = cursor_x = 0;
00024     textsize = 1;
00025     textcolor = 0xFFFF;
00026  }
00027 
00028 void HD66766::goHome(void) {
00029   goTo(0,0);
00030 }
00031 
00032 uint16_t HD66766::width(void) {
00033   return _width;
00034 }
00035 uint16_t HD66766::height(void) {
00036   return _height;
00037 }
00038 uint16_t HD66766::rb_swap(uint16_t c) {
00039     uint16_t rc;
00040     if (_rb_swap == 0) {
00041         rc = c;
00042     }
00043     else {
00044         rc =  c  & 0x07E0;
00045         rc |= (c >> 11) & 0x001F;
00046         rc |= (c & 0x001F) << 11;
00047     }
00048     return rc;
00049 }
00050 
00051 void HD66766::fillScreen(uint16_t color) {
00052     setWriteDir();
00053     writeRegister(0x0021, _gramstart);
00054     writeCommand(0x0022);
00055     _cs = 0;
00056     _rs = 1;
00057     _rd = 1;
00058     _wr = 1;
00059     for (int i = 0x0000; i < 0x5000; i++) {
00060         writeData_unsafe(rb_swap(color));
00061         //wait_ms(10);
00062     }
00063     _cs = 1;
00064 }
00065 
00066 
00067 void HD66766::drawPixel(uint16_t x, uint16_t y, uint16_t color)
00068 {
00069     uint16_t AC;
00070     AC = (y<<8)+x + _gramstart;
00071     writeRegister(0x0021,AC);
00072     writeRegister(0x0022, rb_swap(color)); 
00073 }
00074 
00075 void HD66766::initDisplay(void) {
00076     //uint16_t a, d;
00077     reset();
00078     writeRegister(0x0000, 0x0001);
00079     mirror(1);
00080     //writeRegister(0x0001, 0x0215);  // Driver Output Control
00081     //writeRegister(0x0001, 0x0013);  // Driver Output Control
00082     writeRegister(0x0002, 0x0000); // LCD-Driving-Waveform Control
00083     //writeRegister(0x0003, 0x7e6c); // Power Control 1
00084     //writeRegister(0x0003, 0x6e78); // Power Control 1
00085     writeRegister(0x0003, 0x9e78); // Power Control 1
00086     writeRegister(0x0004, 0x0000); // Contrast Control
00087     //writeRegister(0x0005, 0x0030); // Entry Mode
00088     writeRegister(0x0005, 0x0030); // Entry Mode
00089     writeRegister(0x0007, 0x0003); // Display on
00090     writeRegister(0x000c, 0x0006); // Power Control 2
00091     writeRegister(0x0011, 0x0000); // Vertical Scroll Control
00092     writeRegister(0x0016, 0x7F00); // Set window horizontal position to top to bottom of ram address 127 to 0 (128)
00093     writeRegister(0x0017, 0xAF00); // Set window vertical position to top to bottom of ram address 159 to 0 (160)
00094     writeRegister(0x0020, 0x0000); // RAM Write Data Mask
00095     writeRegister(0x0021, _gramstart); // GRAM Address Set
00096 }
00097 
00098 void HD66766::setWriteDir(void) {
00099         _d.output();
00100 }
00101 
00102 void HD66766::setReadDir(void) {
00103         _d.input();
00104 }
00105 
00106 void HD66766::_write(uint16_t rs, uint16_t d) {
00107     _cs=0;
00108     _rd=1;
00109     _rs=rs;   
00110 
00111     _d.output();
00112     _d=d;
00113     _wr=0;
00114     _delay(1);
00115     _wr=1;
00116 
00117     _cs=1; 
00118 }
00119 
00120 void HD66766::writeData_unsafe(uint16_t d)
00121 {
00122     //_d.output();
00123     _d = d;
00124     _wr = 0;
00125     _delay(1);
00126     _wr = 1;
00127 }
00128 
00129 void HD66766::reset(void)
00130 {
00131     _rst=0;
00132     _delay(1000);
00133     _rst=1;
00134     _delay(1000);
00135  }
00136  
00137 uint16_t HD66766::readData(){
00138     uint16_t d = 0;
00139     _d.input();
00140     _cs = 0;
00141     _rs = 1;
00142     _wr = 1;
00143     _rd = 1;
00144 
00145 
00146     _delay(1);
00147     _rd = 0;
00148     _delay(10);
00149     d = _d;
00150     _rd = 1;
00151     _cs = 1;
00152     return d;
00153 }
00154 
00155 uint16_t HD66766::readRegister(uint16_t addr) {
00156    writeCommand(addr);
00157    return readData();
00158 }
00159 void HD66766::writeRegister(uint16_t addr, uint16_t data) {
00160    writeCommand(addr);
00161    writeData(data);
00162 }
00163 void HD66766::goTo(uint16_t x, uint16_t y) {
00164     uint16_t AC;
00165     AC = (y<<8)+x + _gramstart;
00166     writeRegister(0x0021,AC);
00167 }
00168 
00169 void HD66766::drawVerticalLine(uint16_t x, uint16_t y, uint16_t length, uint16_t color)
00170 {
00171   if (x >= _width) return;
00172 
00173   drawLine(x, y, x, y+length, color);
00174 }
00175 
00176 void HD66766::drawHorizontalLine(uint16_t x, uint16_t y, uint16_t length, uint16_t color)
00177 {
00178   if (y >= _height) return;
00179   drawLine(x, y, x+length, y, color);
00180 }
00181 
00182 void HD66766::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, 
00183               uint16_t color) {
00184   // if you're in rotation 1 or 3, we need to swap the X and Y's
00185 
00186   int16_t steep = abs(y1 - y0) > abs(x1 - x0);
00187   if (steep) {
00188     swap(x0, y0);
00189     swap(x1, y1);
00190   }
00191 
00192   if (x0 > x1) {
00193     swap(x0, x1);
00194     swap(y0, y1);
00195   }
00196 
00197   int16_t dx, dy;
00198   dx = x1 - x0;
00199   //dy = abs(y1 - y0);
00200   dy = abs(y1 - y0);
00201 
00202   int16_t err = dx / 2;
00203   int16_t ystep;
00204 
00205   if (y0 < y1) {
00206     ystep = 1;
00207   } else {
00208     ystep = -1;}
00209 
00210   for (; x0<=x1; x0++) {
00211     if (steep) {
00212       drawPixel(y0, x0, color);
00213     } else {
00214       drawPixel(x0, y0, color);
00215     }
00216     err -= dy;
00217     if (err < 0) {
00218       y0 += ystep;
00219       err += dx;
00220     }
00221   }
00222 }
00223 
00224 
00225 void HD66766::drawTriangle(uint16_t x0, uint16_t y0,
00226               uint16_t x1, uint16_t y1,
00227               uint16_t x2, uint16_t y2, uint16_t color)
00228 {
00229   drawLine(x0, y0, x1, y1, color);
00230   drawLine(x1, y1, x2, y2, color);
00231   drawLine(x2, y2, x0, y0, color); 
00232 }
00233 
00234 void HD66766::fillTriangle ( int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint16_t color)
00235 {
00236   if (y0 > y1) {
00237     swap(y0, y1); swap(x0, x1);
00238   }
00239   if (y1 > y2) {
00240     swap(y2, y1); swap(x2, x1);
00241   }
00242   if (y0 > y1) {
00243     swap(y0, y1); swap(x0, x1);
00244   }
00245 
00246   int32_t dx1, dx2, dx3; // Interpolation deltas
00247   int32_t sx1, sx2, sy; // Scanline co-ordinates
00248 
00249   sx2=(int32_t)x0 * (int32_t)1000; // Use fixed point math for x axis values
00250   sx1 = sx2;
00251   sy=y0;
00252 
00253   // Calculate interpolation deltas
00254   if (y1-y0 > 0) dx1=((x1-x0)*1000)/(y1-y0);
00255     else dx1=0;
00256   if (y2-y0 > 0) dx2=((x2-x0)*1000)/(y2-y0);
00257     else dx2=0;
00258   if (y2-y1 > 0) dx3=((x2-x1)*1000)/(y2-y1);
00259     else dx3=0;
00260 
00261   // Render scanlines (horizontal lines are the fastest rendering method)
00262   if (dx1 > dx2)
00263   {
00264     for(; sy<=y1; sy++, sx1+=dx2, sx2+=dx1)
00265     {
00266       drawHorizontalLine(sx1/1000, sy, (sx2-sx1)/1000, color);
00267     }
00268     sx2 = x1*1000;
00269     sy = y1;
00270     for(; sy<=y2; sy++, sx1+=dx2, sx2+=dx3)
00271     {
00272       drawHorizontalLine(sx1/1000, sy, (sx2-sx1)/1000, color);
00273     }
00274   }
00275   else
00276   {
00277     for(; sy<=y1; sy++, sx1+=dx1, sx2+=dx2)
00278     {
00279       drawHorizontalLine(sx1/1000, sy, (sx2-sx1)/1000, color);
00280     }
00281     sx1 = x1*1000;
00282     sy = y1;
00283     for(; sy<=y2; sy++, sx1+=dx3, sx2+=dx2)
00284     {
00285       drawHorizontalLine(sx1/1000, sy, (sx2-sx1)/1000, color);
00286     }
00287   }
00288 }
00289 
00290 uint16_t HD66766::Color565(uint8_t r, uint8_t g, uint8_t b) {
00291     uint16_t c;
00292     c = r >> 3;
00293     c <<= 6;
00294     c |= g >> 2;
00295     c <<= 5;
00296     c |= b >> 3;
00297 
00298     //printf("%x\r\n", c);
00299     return c;
00300 }
00301 
00302 // draw a rectangle
00303 void HD66766::drawRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, 
00304               uint16_t color) {
00305   // smarter version
00306   drawHorizontalLine(x, y, w, color);
00307   drawHorizontalLine(x, y+h-1, w, color);
00308   drawVerticalLine(x, y, h, color);
00309   drawVerticalLine(x+w-1, y, h, color);
00310 }
00311 
00312 // draw a rounded rectangle
00313 void HD66766::drawRoundRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t r,
00314                uint16_t color) {
00315   // smarter version
00316   drawHorizontalLine(x+r, y, w-2*r, color);
00317   drawHorizontalLine(x+r, y+h-1, w-2*r, color);
00318   drawVerticalLine(x, y+r, h-2*r, color);
00319   drawVerticalLine(x+w-1, y+r, h-2*r, color);
00320   // draw four corners
00321   drawCircleHelper(x+r, y+r, r, 1, color);
00322   drawCircleHelper(x+w-r-1, y+r, r, 2, color);
00323   drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color);
00324   drawCircleHelper(x+r, y+h-r-1, r, 8, color);
00325 }
00326 
00327 
00328 // fill a rounded rectangle
00329 void HD66766::fillRoundRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t r,
00330                uint16_t color) {
00331   // smarter version
00332   fillRect(x+r, y, w-2*r, h, color);
00333 
00334   // draw four corners
00335   fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color);
00336   fillCircleHelper(x+r, y+r, r, 2, h-2*r-1, color);
00337 }
00338 
00339 // fill a circle
00340 void HD66766::fillCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color) {
00341   //writeRegister(TFTLCD_ENTRY_MOD, 0x1030);
00342   drawVerticalLine(x0, y0-r, 2*r+1, color);
00343   fillCircleHelper(x0, y0, r, 3, 0, color);
00344 }
00345 
00346 
00347 // used to do circles and roundrects!
00348 void HD66766::fillCircleHelper(uint16_t x0, uint16_t y0, uint16_t r, uint8_t cornername, uint16_t delta,
00349             uint16_t color) {
00350 
00351   int16_t f = 1 - r;
00352   int16_t ddF_x = 1;
00353   int16_t ddF_y = -2 * r;
00354   int16_t x = 0;
00355   int16_t y = r;
00356 
00357   while (x<y) {
00358     if (f >= 0) {
00359       y--;
00360       ddF_y += 2;
00361       f += ddF_y;
00362     }
00363     x++;
00364     ddF_x += 2;
00365     f += ddF_x;
00366   
00367     if (cornername & 0x1) {
00368       drawVerticalLine(x0+x, y0-y, 2*y+1+delta, color);
00369       drawVerticalLine(x0+y, y0-x, 2*x+1+delta, color);
00370     }
00371     if (cornername & 0x2) {
00372       drawVerticalLine(x0-x, y0-y, 2*y+1+delta, color);
00373       drawVerticalLine(x0-y, y0-x, 2*x+1+delta, color);
00374     }
00375   }
00376 }
00377 
00378 
00379 // draw a circle outline
00380 
00381 void HD66766::drawCircle(uint16_t x0, uint16_t y0, uint16_t r, 
00382             uint16_t color) {
00383   drawPixel(x0, y0+r, color);
00384   drawPixel(x0, y0-r, color);
00385   drawPixel(x0+r, y0, color);
00386   drawPixel(x0-r, y0, color);
00387 
00388   drawCircleHelper(x0, y0, r, 0xF, color);
00389 }
00390 
00391 void HD66766::drawCircleHelper(uint16_t x0, uint16_t y0, uint16_t r, uint8_t cornername,
00392             uint16_t color) {
00393   int16_t f = 1 - r;
00394   int16_t ddF_x = 1;
00395   int16_t ddF_y = -2 * r;
00396   int16_t x = 0;
00397   int16_t y = r;
00398 
00399 
00400   while (x<y) {
00401     if (f >= 0) {
00402       y--;
00403       ddF_y += 2;
00404       f += ddF_y;
00405     }
00406     x++;
00407     ddF_x += 2;
00408     f += ddF_x;
00409     if (cornername & 0x4) {
00410       drawPixel(x0 + x, y0 + y, color);
00411       drawPixel(x0 + y, y0 + x, color);
00412     } 
00413     if (cornername & 0x2) {
00414       drawPixel(x0 + x, y0 - y, color);
00415       drawPixel(x0 + y, y0 - x, color);
00416     }
00417     if (cornername & 0x8) {
00418       drawPixel(x0 - y, y0 + x, color);
00419       drawPixel(x0 - x, y0 + y, color);
00420     }
00421     if (cornername & 0x1) {
00422       drawPixel(x0 - y, y0 - x, color);
00423       drawPixel(x0 - x, y0 - y, color);
00424     }
00425   }
00426 }
00427 
00428 // fill a rectangle
00429 void HD66766::fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, 
00430               uint16_t fillcolor) {
00431   // smarter version
00432   while (h--)
00433     drawHorizontalLine(x, y++, w, fillcolor);
00434 }
00435 
00436 
00437 void HD66766::setCursor(uint16_t x, uint16_t y) {
00438   cursor_x = x;
00439   cursor_y = y;
00440 }
00441 
00442 void HD66766::setTextSize(uint8_t s) {
00443   textsize = s;
00444 }
00445 
00446 void HD66766::setTextColor(uint16_t c) {
00447   textcolor = c;
00448 }
00449 
00450 size_t HD66766::println(char *c){
00451   while (c[0] != 0) {
00452     write(c[0]);
00453     c++;
00454   }
00455     //drawString(cursor_x, cursor_y, c, textcolor);
00456     return sizeof(c);
00457 }
00458 
00459 size_t HD66766::write(uint8_t c) {
00460   if (c == '\n') {
00461     cursor_y += textsize*8;
00462     cursor_x = 0;
00463   } else if (c == '\r') {
00464     // skip em
00465   } else {
00466     drawChar(cursor_x, cursor_y, c, textcolor, textsize);
00467     cursor_x += textsize*6;
00468   }
00469   return 0;
00470 }
00471 
00472 // draw a character
00473 void HD66766::drawChar(uint16_t x, uint16_t y, char c, 
00474               uint16_t color, uint8_t size) {
00475   for (uint8_t i =0; i<5; i++ ) {
00476     uint8_t line = font[(c*5)+i];
00477     for (uint8_t j = 0; j<8; j++) {
00478       if (line & 0x1) {
00479     if (size == 1) // default size
00480       drawPixel(x+i, y+j, color);
00481     else {  // big size
00482       fillRect(x+i*size, y+j*size, size, size, color);
00483     } 
00484       }
00485       line >>= 1;
00486     }
00487   }
00488 }
00489 
00490 void HD66766::mirror(uint16_t d) {
00491     switch(d) {
00492         case 0: {
00493             _gramstart = 0x0000;
00494             _rb_swap = 0;
00495             writeRegister(0x0001, 0x0013);  // Driver Output Control
00496             writeRegister(0x0016, 0x7F00); // Set window horizontal position to top to bottom of ram address 127 to 0 (128)
00497             writeRegister(0x0017, 0xAF00); // Set window vertical position to top to bottom of ram address 159 to 0 (160)
00498             break;
00499             }
00500         case 1: {
00501             _rb_swap = 0;
00502             _gramstart = 0x1000;
00503             writeRegister(0x0001, 0x0215);  // Driver Output Control
00504             writeRegister(0x0016, 0x7F00); // Set window horizontal position to top to bottom of ram address 127 to 0 (128)
00505             writeRegister(0x0017, 0xAF00); // Set window vertical position to top to bottom of ram address 159 to 0 (160)
00506             break;
00507             }
00508         case 2: {
00509             _rb_swap = 1;
00510             _gramstart = 0x0004;
00511             writeRegister(0x0001, 0x0113);  // Driver Output Control
00512             writeRegister(0x0016, 0x8304); // Set window horizontal position to top to bottom of ram address 127 to 0 (128)
00513             writeRegister(0x0017, 0xAF00); // Set window vertical position to top to bottom of ram address 159 to 0 (160)
00514             break;
00515             }
00516         case 3: {
00517             _gramstart = 0x1004;
00518             _rb_swap = 1;
00519             writeRegister(0x0001, 0x0315);  // Driver Output Control
00520             writeRegister(0x0016, 0x8304); // Set window horizontal position to top to bottom of ram address 127 to 0 (128)
00521             writeRegister(0x0017, 0xAF00); // Set window vertical position to top to bottom of ram address 159 to 0 (160)
00522             break;
00523             }
00524     }
00525 }
00526 
00527 void HD66766::_delay(uint16_t t)
00528 {
00529     //wait_us(1);
00530 }