Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
ST7735.cpp
00001 #include "mbed.h" 00002 #include "ST7735.h" 00003 00004 #ifdef LOAD_FONT2 00005 #include "Font16.h" 00006 #endif 00007 00008 #ifdef LOAD_FONT4 00009 #include "Font32.h" 00010 #endif 00011 00012 #ifdef LOAD_FONT6 00013 #include "Font64.h" 00014 #endif 00015 00016 #ifdef LOAD_FONT7 00017 #include "Font7s.h" 00018 #endif 00019 00020 #ifdef LOAD_FONT8 00021 #include "Font72.h" 00022 #endif 00023 00024 00025 ST7735::ST7735(PinName cePin, PinName dcPin, PinName mosiPin, PinName sclkPin) 00026 { 00027 spi = new SPI(mosiPin, NC, sclkPin); // create new SPI instance and initialise 00028 initSPI(); 00029 00030 // set up other pins as required 00031 ce = new DigitalOut(cePin,1); 00032 dc = new DigitalOut(dcPin,0); 00033 00034 // Defaults after power-up 00035 textsize = 1; 00036 textcolor = ST7735_GREEN; 00037 textbgcolor = ST7735_BLACK; 00038 } 00039 00040 // function to initialise SPI peripheral 00041 void ST7735::initSPI() 00042 { 00043 spi->format(8,0); // 8 bits, Mode 0 00044 spi->frequency(20000000); // SPI clock frequency 00045 } 00046 00047 // Write data word 00048 void ST7735::writecommand(char c) 00049 { 00050 dc->write(0); 00051 ce->write(0); 00052 spi->write(c); 00053 ce->write(1); 00054 } 00055 00056 // Write command word 00057 void ST7735::writedata(char c) 00058 { 00059 dc->write(1); 00060 ce->write(0); 00061 spi->write(c); 00062 ce->write(1); 00063 } 00064 00065 00066 // Rather than a bazillion writecommand() and writedata() calls, screen 00067 // initialization commands and arguments are organized in tables 00068 // The table may look bulky, but that's mostly the 00069 // formatting -- storage-wise this is hundreds of bytes more compact 00070 // than the equivalent code. Companion function follows. 00071 #define DELAY 0x80 00072 static const uint8_t Bcmd[] = { // Initialization commands for 7735B screens 00073 18, // 18 commands in list: 00074 ST7735_SWRESET, DELAY, // 1: Software reset, no args, w/delay 00075 50, // 50 ms delay 00076 ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, no args, w/delay 00077 255, // 255 = 500 ms delay 00078 ST7735_COLMOD , 1+DELAY, // 3: Set color mode, 1 arg + delay: 00079 0x05, // 16-bit color 00080 10, // 10 ms delay 00081 ST7735_FRMCTR1, 3+DELAY, // 4: Frame rate control, 3 args + delay: 00082 0x00, // fastest refresh 00083 0x06, // 6 lines front porch 00084 0x03, // 3 lines back porch 00085 10, // 10 ms delay 00086 ST7735_MADCTL , 1 , // 5: Memory access ctrl (directions), 1 arg: 00087 0x08, // Row addr/col addr, bottom to top refresh 00088 ST7735_DISSET5, 2 , // 6: Display settings #5, 2 args, no delay: 00089 0x15, // 1 clk cycle nonoverlap, 2 cycle gate 00090 // rise, 3 cycle osc equalize 00091 0x02, // Fix on VTL 00092 ST7735_INVCTR , 1 , // 7: Display inversion control, 1 arg: 00093 0x0, // Line inversion 00094 ST7735_PWCTR1 , 2+DELAY, // 8: Power control, 2 args + delay: 00095 0x02, // GVDD = 4.7V 00096 0x70, // 1.0uA 00097 10, // 10 ms delay 00098 ST7735_PWCTR2 , 1 , // 9: Power control, 1 arg, no delay: 00099 0x05, // VGH = 14.7V, VGL = -7.35V 00100 ST7735_PWCTR3 , 2 , // 10: Power control, 2 args, no delay: 00101 0x01, // Opamp current small 00102 0x02, // Boost frequency 00103 ST7735_VMCTR1 , 2+DELAY, // 11: Power control, 2 args + delay: 00104 0x3C, // VCOMH = 4V 00105 0x38, // VCOML = -1.1V 00106 10, // 10 ms delay 00107 ST7735_PWCTR6 , 2 , // 12: Power control, 2 args, no delay: 00108 0x11, 0x15, 00109 ST7735_GMCTRP1,16 , // 13: Magical unicorn dust, 16 args, no delay: 00110 0x09, 0x16, 0x09, 0x20, // (seriously though, not sure what 00111 0x21, 0x1B, 0x13, 0x19, // these config values represent) 00112 0x17, 0x15, 0x1E, 0x2B, 00113 0x04, 0x05, 0x02, 0x0E, 00114 ST7735_GMCTRN1,16+DELAY, // 14: Sparkles and rainbows, 16 args + delay: 00115 0x0B, 0x14, 0x08, 0x1E, // (ditto) 00116 0x22, 0x1D, 0x18, 0x1E, 00117 0x1B, 0x1A, 0x24, 0x2B, 00118 0x06, 0x06, 0x02, 0x0F, 00119 10, // 10 ms delay 00120 ST7735_CASET , 4 , // 15: Column addr set, 4 args, no delay: 00121 0x00, 0x02, // XSTART = 2 00122 0x00, 0x81, // XEND = 129 00123 ST7735_RASET , 4 , // 16: Row addr set, 4 args, no delay: 00124 0x00, 0x02, // XSTART = 1 00125 0x00, 0x81, // XEND = 160 00126 ST7735_NORON , DELAY, // 17: Normal display on, no args, w/delay 00127 10, // 10 ms delay 00128 ST7735_DISPON , DELAY, // 18: Main screen turn on, no args, w/delay 00129 255 }, // 255 = 500 ms delay 00130 00131 Rcmd1[] = { // Init for 7735R, part 1 (red or green tab) 00132 15, // 15 commands in list: 00133 ST7735_SWRESET, DELAY, // 1: Software reset, 0 args, w/delay 00134 150, // 150 ms delay 00135 ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, 0 args, w/delay 00136 255, // 500 ms delay 00137 ST7735_FRMCTR1, 3 , // 3: Frame rate ctrl - normal mode, 3 args: 00138 0x01, 0x2C, 0x2D, // Rate = fosc/(1x2+40) * (LINE+2C+2D) 00139 ST7735_FRMCTR2, 3 , // 4: Frame rate control - idle mode, 3 args: 00140 0x01, 0x2C, 0x2D, // Rate = fosc/(1x2+40) * (LINE+2C+2D) 00141 ST7735_FRMCTR3, 6 , // 5: Frame rate ctrl - partial mode, 6 args: 00142 0x01, 0x2C, 0x2D, // Dot inversion mode 00143 0x01, 0x2C, 0x2D, // Line inversion mode 00144 ST7735_INVCTR , 1 , // 6: Display inversion ctrl, 1 arg, no delay: 00145 0x07, // No inversion 00146 ST7735_PWCTR1 , 3 , // 7: Power control, 3 args, no delay: 00147 0xA2, 00148 0x02, // -4.6V 00149 0x84, // AUTO mode 00150 ST7735_PWCTR2 , 1 , // 8: Power control, 1 arg, no delay: 00151 0xC5, // VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD 00152 ST7735_PWCTR3 , 2 , // 9: Power control, 2 args, no delay: 00153 0x0A, // Opamp current small 00154 0x00, // Boost frequency 00155 ST7735_PWCTR4 , 2 , // 10: Power control, 2 args, no delay: 00156 0x8A, // BCLK/2, Opamp current small & Medium low 00157 0x2A, 00158 ST7735_PWCTR5 , 2 , // 11: Power control, 2 args, no delay: 00159 0x8A, 0xEE, 00160 ST7735_VMCTR1 , 1 , // 12: Power control, 1 arg, no delay: 00161 0x0E, 00162 ST7735_INVOFF , 0 , // 13: Don't invert display, no args, no delay 00163 ST7735_MADCTL , 1 , // 14: Memory access control (directions), 1 arg: 00164 0xC8, // row addr/col addr, bottom to top refresh 00165 ST7735_COLMOD , 1 , // 15: set color mode, 1 arg, no delay: 00166 0x05 }, // 16-bit color 00167 00168 Rcmd2green[] = { // Init for 7735R, part 2 (green tab only) 00169 2, // 2 commands in list: 00170 ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay: 00171 0x00, 0x02, // XSTART = 0 00172 0x00, 0x7F+0x02, // XEND = 127 00173 ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay: 00174 0x00, 0x01, // XSTART = 0 00175 0x00, 0x9F+0x01 }, // XEND = 159 00176 Rcmd2red[] = { // Init for 7735R, part 2 (red tab only) 00177 2, // 2 commands in list: 00178 ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay: 00179 0x00, 0x00, // XSTART = 0 00180 0x00, 0x7F, // XEND = 127 00181 ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay: 00182 0x00, 0x00, // XSTART = 0 00183 0x00, 0x9F }, // XEND = 159 00184 00185 Rcmd3[] = { // Init for 7735R, part 3 (red or green tab) 00186 4, // 4 commands in list: 00187 ST7735_GMCTRP1, 16 , // 1: Magical unicorn dust, 16 args, no delay: 00188 0x02, 0x1c, 0x07, 0x12, 00189 0x37, 0x32, 0x29, 0x2d, 00190 0x29, 0x25, 0x2B, 0x39, 00191 0x00, 0x01, 0x03, 0x10, 00192 ST7735_GMCTRN1, 16 , // 2: Sparkles and rainbows, 16 args, no delay: 00193 0x03, 0x1d, 0x07, 0x06, 00194 0x2E, 0x2C, 0x29, 0x2D, 00195 0x2E, 0x2E, 0x37, 0x3F, 00196 0x00, 0x00, 0x02, 0x10, 00197 ST7735_NORON , DELAY, // 3: Normal display on, no args, w/delay 00198 10, // 10 ms delay 00199 ST7735_DISPON , DELAY, // 4: Main screen turn on, no args w/delay 00200 100 }; // 100 ms delay 00201 00202 00203 00204 // Companion code to the above tables. Reads and issues 00205 // a series of LCD commands stored in PROGMEM byte array. 00206 void ST7735::commandList(const uint8_t *addr){ 00207 uint8_t numCommands, numArgs; 00208 uint16_t ms; 00209 00210 numCommands = pgm_read_byte(addr++); // Number of commands to follow 00211 while(numCommands--) { // For each command... 00212 writecommand(pgm_read_byte(addr++)); // Read, issue command 00213 numArgs = pgm_read_byte(addr++); // Number of args to follow 00214 ms = numArgs & DELAY; // If hibit set, delay follows args 00215 numArgs &= ~DELAY; // Mask out delay bit 00216 while(numArgs--) { // For each argument... 00217 writedata(pgm_read_byte(addr++)); // Read, issue argument 00218 } 00219 00220 if(ms) { 00221 ms = pgm_read_byte(addr++); // Read post-command delay time (ms) 00222 if(ms == 255) ms = 500; // If 255, delay for 500 ms 00223 wait_ms(ms); 00224 } 00225 } 00226 } 00227 00228 // Initialization code common to both 'B' and 'R' type displays 00229 void ST7735::commonInit(const uint8_t *cmdList){ 00230 wait_ms(100); // Wait for reset to be stable after power-up 00231 colstart = rowstart = 0; // May be overridden in init func 00232 if(cmdList) commandList(cmdList); 00233 } 00234 00235 // Initialization for ST7735B screens 00236 void ST7735::initB() { 00237 commonInit(Bcmd); 00238 } 00239 00240 // Initialization for ST7735R screens (green or red tabs) 00241 void ST7735::initR(uint8_t options) { 00242 commonInit(Rcmd1); 00243 if(options == INITR_GREENTAB) { 00244 commandList(Rcmd2green); 00245 colstart = 2; 00246 rowstart = 1; 00247 } else { 00248 // colstart, rowstart left at default '0' values 00249 commandList(Rcmd2red); 00250 } 00251 commandList(Rcmd3); 00252 00253 // if black, change MADCTL color filter 00254 if (options == INITR_BLACKTAB) { 00255 writecommand(ST7735_MADCTL); 00256 writedata(0xC0); 00257 } 00258 00259 tabcolor = options; 00260 } 00261 00262 void ST7735::setRotation(uint8_t m) { 00263 00264 writecommand(ST7735_MADCTL); 00265 rotation = m % 4; // can't be higher than 3 00266 switch (rotation) { 00267 case 0: 00268 if (tabcolor == INITR_BLACKTAB) { 00269 writedata(MADCTL_MX | MADCTL_MY | MADCTL_RGB); 00270 } else { 00271 writedata(MADCTL_MX | MADCTL_MY | MADCTL_BGR); 00272 } 00273 _width = ST7735_TFTWIDTH; 00274 _height = ST7735_TFTHEIGHT; 00275 break; 00276 case 1: 00277 if (tabcolor == INITR_BLACKTAB) { 00278 writedata(MADCTL_MY | MADCTL_MV | MADCTL_RGB); 00279 } else { 00280 writedata(MADCTL_MY | MADCTL_MV | MADCTL_BGR); 00281 } 00282 _width = ST7735_TFTHEIGHT; 00283 _height = ST7735_TFTWIDTH; 00284 break; 00285 case 2: 00286 if (tabcolor == INITR_BLACKTAB) { 00287 writedata(MADCTL_RGB); 00288 } else { 00289 writedata(MADCTL_BGR); 00290 } 00291 _width = ST7735_TFTWIDTH; 00292 _height = ST7735_TFTHEIGHT; 00293 break; 00294 case 3: 00295 if (tabcolor == INITR_BLACKTAB) { 00296 writedata(MADCTL_MX | MADCTL_MV | MADCTL_RGB); 00297 } else { 00298 writedata(MADCTL_MX | MADCTL_MV | MADCTL_BGR); 00299 } 00300 _width = ST7735_TFTHEIGHT; 00301 _height = ST7735_TFTWIDTH; 00302 break; 00303 } 00304 } 00305 00306 void ST7735::fillScreen(uint16_t color) { 00307 fillRect(0, 0, _width, _height, color); 00308 } 00309 00310 00311 00312 void ST7735::pushColor(uint16_t color) { 00313 dc->write(1); 00314 ce->write(0); 00315 spi->write(color >> 8); 00316 spi->write(color); 00317 ce->write(1); 00318 } 00319 00320 // fill a rectangle 00321 void ST7735::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { 00322 00323 // rudimentary clipping (drawChar w/big text requires this) 00324 if((x >= _width) || (y >= _height)) return; 00325 if((x + w - 1) >= _width) w = _width - x; 00326 if((y + h - 1) >= _height) h = _height - y; 00327 00328 setAddrWindow(x, y, x+w-1, y+h-1); 00329 00330 uint8_t hi = color >> 8, lo = color; 00331 00332 dc->write(1); 00333 ce->write(0); 00334 00335 for(y=h; y>0; y--) { 00336 for(x=w; x>0; x--) { 00337 spi->write(hi); 00338 spi->write(lo); 00339 } 00340 } 00341 ce->write(1); 00342 } 00343 00344 00345 00346 void ST7735::invertDisplay(bool i) { 00347 writecommand(i ? ST7735_INVON : ST7735_INVOFF); 00348 } 00349 00350 void ST7735::drawPixel(int16_t x, int16_t y, uint16_t color) { 00351 00352 if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; 00353 00354 setAddrWindow(x,y,x+1,y+1); 00355 dc->write(1); 00356 ce->write(0); 00357 spi->write(color >> 8); 00358 spi->write(color); 00359 ce->write(1); 00360 } 00361 00362 void ST7735::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { 00363 00364 // Rudimentary clipping 00365 if((x >= _width) || (y >= _height)) return; 00366 if((y+h-1) >= _height) h = _height-y; 00367 setAddrWindow(x, y, x, y+h-1); 00368 00369 uint8_t hi = color >> 8, lo = color; 00370 00371 dc->write(1); 00372 ce->write(0); 00373 while (h--) { 00374 spi->write(hi); 00375 spi->write(lo); 00376 } 00377 ce->write(1); 00378 } 00379 00380 void ST7735::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { 00381 00382 // Rudimentary clipping 00383 if((x >= _width) || (y >= _height)) return; 00384 if((x+w-1) >= _width) w = _width-x; 00385 setAddrWindow(x, y, x+w-1, y); 00386 uint8_t hi = color >> 8, lo = color; 00387 00388 dc->write(1);; 00389 ce->write(0);; 00390 00391 while (w--) { 00392 spi->write(hi); 00393 spi->write(lo); 00394 } 00395 00396 ce->write(1); 00397 } 00398 00399 // Pass 8-bit (each) R,G,B, get back 16-bit packed color 00400 uint16_t ST7735::Color565(uint8_t r, uint8_t g, uint8_t b) { 00401 return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); 00402 } 00403 00404 // Bresenham's algorithm - thx wikpedia 00405 void ST7735::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) { 00406 int16_t steep = abs(y1 - y0) > abs(x1 - x0); 00407 if (steep) { 00408 swap(x0, y0); 00409 swap(x1, y1); 00410 } 00411 00412 if (x0 > x1) { 00413 swap(x0, x1); 00414 swap(y0, y1); 00415 } 00416 00417 int16_t dx, dy; 00418 dx = x1 - x0; 00419 dy = abs(y1 - y0); 00420 00421 int16_t err = dx / 2; 00422 int16_t ystep; 00423 00424 if (y0 < y1) { 00425 ystep = 1; 00426 } else { 00427 ystep = -1; 00428 } 00429 00430 for (; x0<=x1; x0++) { 00431 if (steep) { 00432 drawPixel(y0, x0, color); 00433 } else { 00434 drawPixel(x0, y0, color); 00435 } 00436 err -= dy; 00437 if (err < 0) { 00438 y0 += ystep; 00439 err += dx; 00440 } 00441 } 00442 } 00443 00444 // Draw a rectangle 00445 void ST7735::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { 00446 drawFastHLine(x, y, w, color); 00447 drawFastHLine(x, y+h-1, w, color); 00448 drawFastVLine(x, y, h, color); 00449 drawFastVLine(x+w-1, y, h, color); 00450 } 00451 00452 // Draw a circle outline 00453 void ST7735::drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color) { 00454 int16_t f = 1 - r; 00455 int16_t ddF_x = 1; 00456 int16_t ddF_y = -2 * r; 00457 int16_t x = 0; 00458 int16_t y = r; 00459 00460 drawPixel(x0 , y0+r, color); 00461 drawPixel(x0 , y0-r, color); 00462 drawPixel(x0+r, y0 , color); 00463 drawPixel(x0-r, y0 , color); 00464 00465 while (x<y) { 00466 if (f >= 0) { 00467 y--; 00468 ddF_y += 2; 00469 f += ddF_y; 00470 } 00471 x++; 00472 ddF_x += 2; 00473 f += ddF_x; 00474 00475 drawPixel(x0 + x, y0 + y, color); 00476 drawPixel(x0 - x, y0 + y, color); 00477 drawPixel(x0 + x, y0 - y, color); 00478 drawPixel(x0 - x, y0 - y, color); 00479 drawPixel(x0 + y, y0 + x, color); 00480 drawPixel(x0 - y, y0 + x, color); 00481 drawPixel(x0 + y, y0 - x, color); 00482 drawPixel(x0 - y, y0 - x, color); 00483 } 00484 } 00485 00486 void ST7735::drawCircleHelper( int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color) { 00487 int16_t f = 1 - r; 00488 int16_t ddF_x = 1; 00489 int16_t ddF_y = -2 * r; 00490 int16_t x = 0; 00491 int16_t y = r; 00492 00493 while (x<y) { 00494 if (f >= 0) { 00495 y--; 00496 ddF_y += 2; 00497 f += ddF_y; 00498 } 00499 x++; 00500 ddF_x += 2; 00501 f += ddF_x; 00502 if (cornername & 0x4) { 00503 drawPixel(x0 + x, y0 + y, color); 00504 drawPixel(x0 + y, y0 + x, color); 00505 } 00506 if (cornername & 0x2) { 00507 drawPixel(x0 + x, y0 - y, color); 00508 drawPixel(x0 + y, y0 - x, color); 00509 } 00510 if (cornername & 0x8) { 00511 drawPixel(x0 - y, y0 + x, color); 00512 drawPixel(x0 - x, y0 + y, color); 00513 } 00514 if (cornername & 0x1) { 00515 drawPixel(x0 - y, y0 - x, color); 00516 drawPixel(x0 - x, y0 - y, color); 00517 } 00518 } 00519 } 00520 00521 void ST7735::fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color) { 00522 drawFastVLine(x0, y0-r, 2*r+1, color); 00523 fillCircleHelper(x0, y0, r, 3, 0, color); 00524 } 00525 00526 // Used to do circles and roundrects 00527 void ST7735::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color) { 00528 00529 int16_t f = 1 - r; 00530 int16_t ddF_x = 1; 00531 int16_t ddF_y = -2 * r; 00532 int16_t x = 0; 00533 int16_t y = r; 00534 00535 while (x<y) { 00536 if (f >= 0) { 00537 y--; 00538 ddF_y += 2; 00539 f += ddF_y; 00540 } 00541 x++; 00542 ddF_x += 2; 00543 f += ddF_x; 00544 00545 if (cornername & 0x1) { 00546 drawFastVLine(x0+x, y0-y, 2*y+1+delta, color); 00547 drawFastVLine(x0+y, y0-x, 2*x+1+delta, color); 00548 } 00549 if (cornername & 0x2) { 00550 drawFastVLine(x0-x, y0-y, 2*y+1+delta, color); 00551 drawFastVLine(x0-y, y0-x, 2*x+1+delta, color); 00552 } 00553 } 00554 } 00555 00556 00557 // Draw a triangle 00558 void ST7735::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) { 00559 drawLine(x0, y0, x1, y1, color); 00560 drawLine(x1, y1, x2, y2, color); 00561 drawLine(x2, y2, x0, y0, color); 00562 } 00563 00564 // Fill a triangle 00565 void ST7735::fillTriangle ( int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) { 00566 00567 int16_t a, b, y, last; 00568 00569 // Sort coordinates by Y order (y2 >= y1 >= y0) 00570 if (y0 > y1) { 00571 swap(y0, y1); swap(x0, x1); 00572 } 00573 if (y1 > y2) { 00574 swap(y2, y1); swap(x2, x1); 00575 } 00576 if (y0 > y1) { 00577 swap(y0, y1); swap(x0, x1); 00578 } 00579 00580 if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing 00581 a = b = x0; 00582 if(x1 < a) a = x1; 00583 else if(x1 > b) b = x1; 00584 if(x2 < a) a = x2; 00585 else if(x2 > b) b = x2; 00586 drawFastHLine(a, y0, b-a+1, color); 00587 return; 00588 } 00589 00590 int16_t 00591 dx01 = x1 - x0, 00592 dy01 = y1 - y0, 00593 dx02 = x2 - x0, 00594 dy02 = y2 - y0, 00595 dx12 = x2 - x1, 00596 dy12 = y2 - y1, 00597 sa = 0, 00598 sb = 0; 00599 00600 // For upper part of triangle, find scanline crossings for segments 00601 // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 00602 // is included here (and second loop will be skipped, avoiding a /0 00603 // error there), otherwise scanline y1 is skipped here and handled 00604 // in the second loop...which also avoids a /0 error here if y0=y1 00605 // (flat-topped triangle). 00606 if(y1 == y2) last = y1; // Include y1 scanline 00607 else last = y1-1; // Skip it 00608 00609 for(y=y0; y<=last; y++) { 00610 a = x0 + sa / dy01; 00611 b = x0 + sb / dy02; 00612 sa += dx01; 00613 sb += dx02; 00614 /* longhand: 00615 a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); 00616 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 00617 */ 00618 if(a > b) swap(a,b); 00619 drawFastHLine(a, y, b-a+1, color); 00620 } 00621 00622 // For lower part of triangle, find scanline crossings for segments 00623 // 0-2 and 1-2. This loop is skipped if y1=y2. 00624 sa = dx12 * (y - y1); 00625 sb = dx02 * (y - y0); 00626 for(; y<=y2; y++) { 00627 a = x1 + sa / dy12; 00628 b = x0 + sb / dy02; 00629 sa += dx12; 00630 sb += dx02; 00631 /* longhand: 00632 a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); 00633 b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); 00634 */ 00635 if(a > b) swap(a,b); 00636 drawFastHLine(a, y, b-a+1, color); 00637 } 00638 } 00639 00640 // Draw a rounded rectangle 00641 void ST7735::drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color) { 00642 // smarter version 00643 drawFastHLine(x+r , y , w-2*r, color); // Top 00644 drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom 00645 drawFastVLine(x , y+r , h-2*r, color); // Left 00646 drawFastVLine(x+w-1, y+r , h-2*r, color); // Right 00647 // draw four corners 00648 drawCircleHelper(x+r , y+r , r, 1, color); 00649 drawCircleHelper(x+w-r-1, y+r , r, 2, color); 00650 drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color); 00651 drawCircleHelper(x+r , y+h-r-1, r, 8, color); 00652 } 00653 00654 // Fill a rounded rectangle 00655 void ST7735::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color) { 00656 // smarter version 00657 fillRect(x+r, y, w-2*r, h, color); 00658 00659 // draw four corners 00660 fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color); 00661 fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color); 00662 } 00663 00664 void ST7735::setCursor(int16_t x, int16_t y) { 00665 cursor_x = x; 00666 cursor_y = y; 00667 } 00668 00669 void ST7735::setTextSize(uint8_t s) { 00670 textsize = (s > 0) ? s : 1; 00671 } 00672 00673 00674 void ST7735::setTextColor(uint16_t c) { 00675 // For 'transparent' background, we'll set the bg 00676 // to the same as fg instead of using a flag 00677 textcolor = textbgcolor = c; 00678 } 00679 00680 void ST7735::setTextColor(uint16_t c, uint16_t b) { 00681 textcolor = c; 00682 textbgcolor = b; 00683 } 00684 00685 void ST7735::setTextWrap(bool w) { 00686 wrap = w; 00687 } 00688 00689 uint8_t ST7735::getRotation(void) { 00690 return rotation; 00691 } 00692 00693 void ST7735::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) { 00694 00695 int16_t i, j, byteWidth = (w + 7) / 8; 00696 00697 for(j=0; j<h; j++) { 00698 for(i=0; i<w; i++ ) { 00699 if(pgm_read_byte(bitmap + j * byteWidth + i / 8) & (128 >> (i & 7))) { 00700 drawPixel(x+i, y+j, color); 00701 } 00702 } 00703 } 00704 } 00705 00706 00707 /*************************************************************************************** 00708 ** Function name: drawUnicode 00709 ** Descriptions: draw a unicode 00710 ***************************************************************************************/ 00711 int ST7735::drawUnicode(unsigned int uniCode, int x, int y, int font) 00712 { 00713 00714 if (font) uniCode -= 32; 00715 00716 unsigned int width = 0; 00717 unsigned int height = 0; 00718 unsigned int flash_address = 0; 00719 int8_t gap = 0; 00720 00721 // if (size == 1) { 00722 // flash_address = pgm_read_word(&chrtbl_f8[uniCode]); 00723 // width = pgm_read_byte(widtbl_f8+uniCode); 00724 // height = chr_hgt_f8; 00725 // gap = 1; 00726 // } 00727 #ifdef LOAD_FONT2 00728 if (font == 2) { 00729 flash_address = pgm_read_word(&chrtbl_f16[uniCode]); 00730 width = pgm_read_byte(widtbl_f16+uniCode); 00731 height = chr_hgt_f16; 00732 gap = 1; 00733 } 00734 #endif 00735 // if (font == 3) { 00736 // flash_address = pgm_read_word(&chrtbl_f24[uniCode]); 00737 // width = pgm_read_byte(widtbl_f24+uniCode); 00738 // height = chr_hgt_f24; 00739 // gap = 0; 00740 // } 00741 #ifdef LOAD_FONT4 00742 if (font == 4) { 00743 flash_address = pgm_read_word(&chrtbl_f32[uniCode]); 00744 width = pgm_read_byte(widtbl_f32+uniCode); 00745 height = chr_hgt_f32; 00746 gap = -3; 00747 } 00748 #endif 00749 // if (font == 5) { 00750 // flash_address = pgm_read_word(&chrtbl_f48[uniCode]); 00751 // width = pgm_read_byte(widtbl_f48+uniCode); 00752 // height = chr_hgt_f48; 00753 // gap = -3; 00754 // } 00755 #ifdef LOAD_FONT6 00756 if (font == 6) { 00757 flash_address = pgm_read_word(&chrtbl_f64[uniCode]); 00758 width = pgm_read_byte(widtbl_f64+uniCode); 00759 height = chr_hgt_f64; 00760 gap = -3; 00761 } 00762 #endif 00763 #ifdef LOAD_FONT7 00764 if (font == 7) { 00765 flash_address = pgm_read_word(&chrtbl_f7s[uniCode]); 00766 width = pgm_read_byte(widtbl_f7s+uniCode); 00767 height = chr_hgt_f7s; 00768 gap = 2; 00769 } 00770 #endif 00771 #ifdef LOAD_FONT8 00772 if (font == 8) { 00773 flash_address = pgm_read_word(&chrtbl_f72[uniCode]); 00774 width = pgm_read_byte(widtbl_f72+uniCode); 00775 height = chr_hgt_f72; 00776 gap = 2; 00777 } 00778 #endif 00779 00780 00781 int w = (width+7)/8; 00782 int pX = 0; 00783 int pY = y; 00784 //int color = 0; 00785 char line = 0; 00786 00787 //fillRect(x,pY,width+gap,height,textbgcolor); 00788 00789 for(int i=0; i<height; i++) 00790 { 00791 if (textcolor != textbgcolor) { 00792 if (textsize == 1) drawFastHLine(x, pY, width+gap, textbgcolor); 00793 else fillRect(x, pY, (width+gap)*textsize, textsize, textbgcolor); 00794 } 00795 for (int k = 0;k < w; k++) 00796 { 00797 line = pgm_read_byte(flash_address+w*i+k); 00798 if(line) { 00799 if (textsize==1){ 00800 pX = x + k*8; 00801 if(line & 0x80) drawPixel(pX, pY, textcolor); 00802 if(line & 0x40) drawPixel(pX+1, pY, textcolor); 00803 if(line & 0x20) drawPixel(pX+2, pY, textcolor); 00804 if(line & 0x10) drawPixel(pX+3, pY, textcolor); 00805 if(line & 0x8) drawPixel(pX+4, pY, textcolor); 00806 if(line & 0x4) drawPixel(pX+5, pY, textcolor); 00807 if(line & 0x2) drawPixel(pX+6, pY, textcolor); 00808 if(line & 0x1) drawPixel(pX+7, pY, textcolor); 00809 } 00810 else { 00811 pX = x + k*8*textsize; 00812 if(line & 0x80) fillRect(pX, pY, textsize, textsize, textcolor); 00813 if(line & 0x40) fillRect(pX+textsize, pY, textsize, textsize, textcolor); 00814 if(line & 0x20) fillRect(pX+2*textsize, pY, textsize, textsize, textcolor); 00815 if(line & 0x10) fillRect(pX+3*textsize, pY, textsize, textsize, textcolor); 00816 if(line & 0x8) fillRect(pX+4*textsize, pY, textsize, textsize, textcolor); 00817 if(line & 0x4) fillRect(pX+5*textsize, pY, textsize, textsize, textcolor); 00818 if(line & 0x2) fillRect(pX+6*textsize, pY, textsize, textsize, textcolor); 00819 if(line & 0x1) fillRect(pX+7*textsize, pY, textsize, textsize, textcolor); 00820 } 00821 } 00822 } 00823 pY+=textsize; 00824 } 00825 return (width+gap)*textsize; // x + 00826 } 00827 00828 /*************************************************************************************** 00829 ** Function name: drawNumber unsigned with size 00830 ** Descriptions: drawNumber 00831 ***************************************************************************************/ 00832 int ST7735::drawNumber(long long_num,int poX, int poY, int font) 00833 { 00834 char tmp[10]; 00835 if (long_num < 0) sprintf(tmp, "%li", long_num); 00836 else sprintf(tmp, "%lu", long_num); 00837 return drawString(tmp, poX, poY, font); 00838 } 00839 00840 /*************************************************************************************** 00841 ** Function name: drawChar 00842 ** Descriptions: draw char 00843 ***************************************************************************************/ 00844 int ST7735::drawChar(char c, int x, int y, int font) 00845 { 00846 return drawUnicode(c, x, y, font); 00847 } 00848 00849 /*************************************************************************************** 00850 ** Function name: drawString 00851 ** Descriptions: draw string 00852 ***************************************************************************************/ 00853 int ST7735::drawString(char *string, int poX, int poY, int font) 00854 { 00855 int sumX = 0; 00856 00857 while(*string) 00858 { 00859 int xPlus = drawChar(*string, poX, poY, font); 00860 sumX += xPlus; 00861 *string++; 00862 poX += xPlus; /* Move cursor right */ 00863 } 00864 return sumX; 00865 } 00866 00867 /*************************************************************************************** 00868 ** Function name: drawCentreString 00869 ** Descriptions: draw string across centre 00870 ***************************************************************************************/ 00871 int ST7735::drawCentreString(char *string, int dX, int poY, int font) 00872 { 00873 int sumX = 0; 00874 int len = 0; 00875 char *pointer = string; 00876 char ascii; 00877 00878 while(*pointer) 00879 { 00880 ascii = *pointer; 00881 //if (font==0)len += 1+pgm_read_byte(widtbl_log+ascii); 00882 //if (font==1)len += 1+pgm_read_byte(widtbl_f8+ascii-32); 00883 #ifdef LOAD_FONT2 00884 if (font==2)len += 1+pgm_read_byte(widtbl_f16+ascii-32); 00885 #endif 00886 //if (font==3)len += 1+pgm_read_byte(widtbl_f48+ascii-32)/2; 00887 #ifdef LOAD_FONT4 00888 if (font==4)len += pgm_read_byte(widtbl_f32+ascii-32)-3; 00889 #endif 00890 //if (font==5) len += pgm_read_byte(widtbl_f48+ascii-32)-3; 00891 #ifdef LOAD_FONT6 00892 if (font==6) len += pgm_read_byte(widtbl_f64+ascii-32)-3; 00893 #endif 00894 #ifdef LOAD_FONT7 00895 if (font==7) len += pgm_read_byte(widtbl_f7s+ascii-32)+2; 00896 #endif 00897 #ifdef LOAD_FONT8 00898 if (font==8) len += pgm_read_byte(widtbl_f72+ascii-32)+2; 00899 #endif 00900 *pointer++; 00901 } 00902 len = len*textsize; 00903 int poX = dX - len/2; 00904 00905 if (poX < 0) poX = 0; 00906 00907 while(*string) 00908 { 00909 00910 int xPlus = drawChar(*string, poX, poY, font); 00911 sumX += xPlus; 00912 *string++; 00913 poX += xPlus; /* Move cursor right */ 00914 } 00915 00916 return sumX; 00917 } 00918 00919 /*************************************************************************************** 00920 ** Function name: drawRightString 00921 ** Descriptions: draw string right justified 00922 ***************************************************************************************/ 00923 int ST7735::drawRightString(char *string, int dX, int poY, int font) 00924 { 00925 int sumX = 0; 00926 int len = 0; 00927 char *pointer = string; 00928 char ascii; 00929 00930 while(*pointer) 00931 { 00932 ascii = *pointer; 00933 //if (font==0)len += 1+pgm_read_byte(widtbl_log+ascii); 00934 //if (font==1)len += 1+pgm_read_byte(widtbl_f8+ascii-32); 00935 #ifdef LOAD_FONT2 00936 if (font==2)len += 1+pgm_read_byte(widtbl_f16+ascii-32); 00937 #endif 00938 //if (font==3)len += 1+pgm_read_byte(widtbl_f48+ascii-32)/2; 00939 #ifdef LOAD_FONT4 00940 if (font==4)len += pgm_read_byte(widtbl_f32+ascii-32)-3; 00941 #endif 00942 //if (font==5) len += pgm_read_byte(widtbl_f48+ascii-32)-3; 00943 #ifdef LOAD_FONT6 00944 if (font==6) len += pgm_read_byte(widtbl_f64+ascii-32)-3; 00945 #endif 00946 #ifdef LOAD_FONT7 00947 if (font==7) len += pgm_read_byte(widtbl_f7s+ascii-32)+2; 00948 #endif 00949 #ifdef LOAD_FONT8 00950 if (font==8) len += pgm_read_byte(widtbl_f72+ascii-32)+2; 00951 #endif 00952 *pointer++; 00953 } 00954 00955 len = len*textsize; 00956 int poX = dX - len; 00957 00958 if (poX < 0) poX = 0; 00959 00960 while(*string) 00961 { 00962 00963 int xPlus = drawChar(*string, poX, poY, font); 00964 sumX += xPlus; 00965 *string++; 00966 poX += xPlus; /* Move cursor right */ 00967 } 00968 00969 return sumX; 00970 } 00971 00972 /*************************************************************************************** 00973 ** Function name: drawFloat 00974 ** Descriptions: drawFloat 00975 ***************************************************************************************/ 00976 int ST7735::drawFloat(float floatNumber, int decimal, int poX, int poY, int font) 00977 { 00978 unsigned long temp=0; 00979 float decy=0.0; 00980 float rounding = 0.5; 00981 00982 float eep = 0.000001; 00983 00984 int sumX = 0; 00985 int xPlus = 0; 00986 00987 if(floatNumber-0.0 < eep) // floatNumber < 0 00988 { 00989 xPlus = drawChar('-',poX, poY, font); 00990 floatNumber = -floatNumber; 00991 00992 poX += xPlus; 00993 sumX += xPlus; 00994 } 00995 00996 for (unsigned char i=0; i<decimal; ++i) 00997 { 00998 rounding /= 10.0; 00999 } 01000 01001 floatNumber += rounding; 01002 01003 temp = (long)floatNumber; 01004 01005 01006 xPlus = drawNumber(temp,poX, poY, font); 01007 01008 poX += xPlus; 01009 sumX += xPlus; 01010 01011 if(decimal>0) 01012 { 01013 xPlus = drawChar('.',poX, poY, font); 01014 poX += xPlus; /* Move cursor right */ 01015 sumX += xPlus; 01016 } 01017 else 01018 { 01019 return sumX; 01020 } 01021 01022 decy = floatNumber - temp; 01023 for(unsigned char i=0; i<decimal; i++) 01024 { 01025 decy *= 10; /* for the next decimal */ 01026 temp = decy; /* get the decimal */ 01027 xPlus = drawNumber(temp,poX, poY, font); 01028 01029 poX += xPlus; /* Move cursor right */ 01030 sumX += xPlus; 01031 decy -= temp; 01032 } 01033 return sumX; 01034 } 01035 01036 void ST7735::setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) { 01037 01038 writecommand(ST7735_CASET); // Column addr set 01039 writedata(0x00); 01040 writedata(x0+colstart); // XSTART 01041 writedata(0x00); 01042 writedata(x1+colstart); // XEND 01043 01044 writecommand(ST7735_RASET); // Row addr set 01045 writedata(0x00); 01046 writedata(y0+rowstart); // YSTART 01047 writedata(0x00); 01048 writedata(y1+rowstart); // YEND 01049 01050 writecommand(ST7735_RAMWR); // write to RAM 01051 } 01052 01053
Generated on Wed Jul 13 2022 21:17:58 by
1.7.2