Fork of the Adafruit ST7735R library targeted to the 1.44" TFT with custom high speed monochrome and color drawing routines. Note that this library includes modifications to use a shared SPI module to simplify projects that use the SPI for several peripherals. Read the WIKI to see how to get this library working in your own project.
Fork of Adafruit_ST7735 by
Adafruit_ST7735.cpp
00001 /*************************************************** 00002 This is a library for the Adafruit 1.8" SPI display. 00003 This library works with the Adafruit 1.8" TFT Breakout w/SD card 00004 ----> http://www.adafruit.com/products/358 00005 as well as Adafruit raw 1.8" TFT display 00006 ----> http://www.adafruit.com/products/618 00007 00008 Check out the links above for our tutorials and wiring diagrams 00009 These displays use SPI to communicate, 4 or 5 pins are required to 00010 interface (RST is optional) 00011 Adafruit invests time and resources providing this open source code, 00012 please support Adafruit and open-source hardware by purchasing 00013 products from Adafruit! 00014 00015 Written by Limor Fried/Ladyada for Adafruit Industries. 00016 MIT license, all text above must be included in any redistribution 00017 ****************************************************/ 00018 00019 #include "mbed.h" 00020 #include "Adafruit_ST7735.h" 00021 #include "board.h" 00022 00023 // Constructor 00024 Adafruit_ST7735::Adafruit_ST7735(PinName cs, PinName rs, PinName rst, PinName bl ) 00025 : _cs(cs), _rs(rs), _rst(rst), _bl(bl), Adafruit_GFX(ST7735_TFTWIDTH, ST7735_TFTHEIGHT) 00026 { } 00027 00028 void Adafruit_ST7735::chipEnable() 00029 { 00030 spi_mutex.lock(); // Get exclusive access to this port 00031 _cs = 0; 00032 } 00033 00034 void Adafruit_ST7735::chipDisable() 00035 { 00036 _cs = 1; 00037 spi_mutex.unlock(); // Renouce exclusive access to this port 00038 } 00039 00040 void Adafruit_ST7735::writecommand(uint8_t c) 00041 { 00042 _rs = 0; 00043 chipEnable(); 00044 spi_port.write( c ); 00045 chipDisable(); 00046 } 00047 00048 void Adafruit_ST7735::writedata(uint8_t c) 00049 { 00050 _rs = 1; 00051 chipEnable(); 00052 spi_port.write( c ); 00053 chipDisable(); 00054 } 00055 00056 00057 // Rather than a bazillion writecommand() and writedata() calls, screen 00058 // initialization commands and arguments are organized in these tables 00059 // stored in PROGMEM. The table may look bulky, but that's mostly the 00060 // formatting -- storage-wise this is hundreds of bytes more compact 00061 // than the equivalent code. Companion function follows. 00062 #define DELAY 0x80 00063 static unsigned char 00064 Bcmd[] = { // Initialization commands for 7735B screens 00065 18, // 18 commands in list: 00066 ST7735_SWRESET, DELAY, // 1: Software reset, no args, w/delay 00067 50, // 50 ms delay 00068 ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, no args, w/delay 00069 255, // 255 = 500 ms delay 00070 ST7735_COLMOD , 1+DELAY, // 3: Set color mode, 1 arg + delay: 00071 0x05, // 16-bit color 00072 10, // 10 ms delay 00073 ST7735_FRMCTR1, 3+DELAY, // 4: Frame rate control, 3 args + delay: 00074 0x00, // fastest refresh 00075 0x06, // 6 lines front porch 00076 0x03, // 3 lines back porch 00077 10, // 10 ms delay 00078 ST7735_MADCTL , 1 , // 5: Memory access ctrl (directions), 1 arg: 00079 0x08, // Row addr/col addr, bottom to top refresh 00080 ST7735_DISSET5, 2 , // 6: Display settings #5, 2 args, no delay: 00081 0x15, // 1 clk cycle nonoverlap, 2 cycle gate 00082 // rise, 3 cycle osc equalize 00083 0x02, // Fix on VTL 00084 ST7735_INVCTR , 1 , // 7: Display inversion control, 1 arg: 00085 0x0, // Line inversion 00086 ST7735_PWCTR1 , 2+DELAY, // 8: Power control, 2 args + delay: 00087 0x02, // GVDD = 4.7V 00088 0x70, // 1.0uA 00089 10, // 10 ms delay 00090 ST7735_PWCTR2 , 1 , // 9: Power control, 1 arg, no delay: 00091 0x05, // VGH = 14.7V, VGL = -7.35V 00092 ST7735_PWCTR3 , 2 , // 10: Power control, 2 args, no delay: 00093 0x01, // Opamp current small 00094 0x02, // Boost frequency 00095 ST7735_VMCTR1 , 2+DELAY, // 11: Power control, 2 args + delay: 00096 0x3C, // VCOMH = 4V 00097 0x38, // VCOML = -1.1V 00098 10, // 10 ms delay 00099 ST7735_PWCTR6 , 2 , // 12: Power control, 2 args, no delay: 00100 0x11, 0x15, 00101 ST7735_GMCTRP1,16 , // 13: Magical unicorn dust, 16 args, no delay: 00102 0x09, 0x16, 0x09, 0x20, // (seriously though, not sure what 00103 0x21, 0x1B, 0x13, 0x19, // these config values represent) 00104 0x17, 0x15, 0x1E, 0x2B, 00105 0x04, 0x05, 0x02, 0x0E, 00106 ST7735_GMCTRN1,16+DELAY, // 14: Sparkles and rainbows, 16 args + delay: 00107 0x0B, 0x14, 0x08, 0x1E, // (ditto) 00108 0x22, 0x1D, 0x18, 0x1E, 00109 0x1B, 0x1A, 0x24, 0x2B, 00110 0x06, 0x06, 0x02, 0x0F, 00111 10, // 10 ms delay 00112 ST7735_CASET , 4 , // 15: Column addr set, 4 args, no delay: 00113 0x00, 0x02, // XSTART = 2 00114 0x00, 0x81, // XEND = 129 00115 ST7735_RASET , 4 , // 16: Row addr set, 4 args, no delay: 00116 0x00, 0x02, // XSTART = 1 00117 0x00, 0x81, // XEND = 160 00118 ST7735_NORON , DELAY, // 17: Normal display on, no args, w/delay 00119 10, // 10 ms delay 00120 ST7735_DISPON , DELAY, // 18: Main screen turn on, no args, w/delay 00121 255 00122 }, // 255 = 500 ms delay 00123 00124 Rcmd1[] = { // Init for 7735R, part 1 (red or green tab) 00125 15, // 15 commands in list: 00126 ST7735_SWRESET, DELAY, // 1: Software reset, 0 args, w/delay 00127 150, // 150 ms delay 00128 ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, 0 args, w/delay 00129 255, // 500 ms delay 00130 ST7735_FRMCTR1, 3 , // 3: Frame rate ctrl - normal mode, 3 args: 00131 0x01, 0x2C, 0x2D, // Rate = fosc/(1x2+40) * (LINE+2C+2D) 00132 ST7735_FRMCTR2, 3 , // 4: Frame rate control - idle mode, 3 args: 00133 0x01, 0x2C, 0x2D, // Rate = fosc/(1x2+40) * (LINE+2C+2D) 00134 ST7735_FRMCTR3, 6 , // 5: Frame rate ctrl - partial mode, 6 args: 00135 0x01, 0x2C, 0x2D, // Dot inversion mode 00136 0x01, 0x2C, 0x2D, // Line inversion mode 00137 ST7735_INVCTR , 1 , // 6: Display inversion ctrl, 1 arg, no delay: 00138 0x07, // No inversion 00139 ST7735_PWCTR1 , 3 , // 7: Power control, 3 args, no delay: 00140 0xA2, 00141 0x02, // -4.6V 00142 0x84, // AUTO mode 00143 ST7735_PWCTR2 , 1 , // 8: Power control, 1 arg, no delay: 00144 0xC5, // VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD 00145 ST7735_PWCTR3 , 2 , // 9: Power control, 2 args, no delay: 00146 0x0A, // Opamp current small 00147 0x00, // Boost frequency 00148 ST7735_PWCTR4 , 2 , // 10: Power control, 2 args, no delay: 00149 0x8A, // BCLK/2, Opamp current small & Medium low 00150 0x2A, 00151 ST7735_PWCTR5 , 2 , // 11: Power control, 2 args, no delay: 00152 0x8A, 0xEE, 00153 ST7735_VMCTR1 , 1 , // 12: Power control, 1 arg, no delay: 00154 0x0E, 00155 ST7735_INVOFF , 0 , // 13: Don't invert display, no args, no delay 00156 ST7735_MADCTL , 1 , // 14: Memory access control (directions), 1 arg: 00157 0xC8, // row addr/col addr, bottom to top refresh 00158 ST7735_COLMOD , 1 , // 15: set color mode, 1 arg, no delay: 00159 0x05 00160 }, // 16-bit color 00161 00162 Rcmd2green[] = { // Init for 7735R, part 2 (green tab only) 00163 2, // 2 commands in list: 00164 ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay: 00165 0x00, 0x02, // XSTART = 0 00166 0x00, 0x7F+0x02, // XEND = 127 00167 ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay: 00168 0x00, 0x01, // XSTART = 0 00169 0x00, 0x9F+0x01 00170 }, // XEND = 159 00171 Rcmd2red[] = { // Init for 7735R, part 2 (red tab only) 00172 2, // 2 commands in list: 00173 ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay: 00174 0x00, 0x00, // XSTART = 0 00175 0x00, 0x7F, // XEND = 127 00176 ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay: 00177 0x00, 0x00, // XSTART = 0 00178 0x00, 0x9F 00179 }, // XEND = 159 00180 00181 Rcmd2green144[] = { // Init for 7735R, part 2 (green 1.44 tab) 00182 2, // 2 commands in list: 00183 ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay: 00184 0x00, 0x00, // XSTART = 0 00185 0x00, 0x7F, // XEND = 127 00186 ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay: 00187 0x00, 0x00, // XSTART = 0 00188 0x00, 0x7F // XEND = 127 00189 }, 00190 00191 Rcmd3[] = { // Init for 7735R, part 3 (red or green tab) 00192 4, // 4 commands in list: 00193 ST7735_GMCTRP1, 16 , // 1: Magical unicorn dust, 16 args, no delay: 00194 0x02, 0x1c, 0x07, 0x12, 00195 0x37, 0x32, 0x29, 0x2d, 00196 0x29, 0x25, 0x2B, 0x39, 00197 0x00, 0x01, 0x03, 0x10, 00198 ST7735_GMCTRN1, 16 , // 2: Sparkles and rainbows, 16 args, no delay: 00199 0x03, 0x1d, 0x07, 0x06, 00200 0x2E, 0x2C, 0x29, 0x2D, 00201 0x2E, 0x2E, 0x37, 0x3F, 00202 0x00, 0x00, 0x02, 0x10, 00203 ST7735_NORON , DELAY, // 3: Normal display on, no args, w/delay 00204 10, // 10 ms delay 00205 ST7735_DISPON , DELAY, // 4: Main screen turn on, no args w/delay 00206 100 00207 }; // 100 ms delay 00208 00209 00210 // Companion code to the above tables. Reads and issues 00211 // a series of LCD commands stored in byte array. 00212 void Adafruit_ST7735::commandList(uint8_t *addr) 00213 { 00214 00215 uint8_t numCommands, numArgs; 00216 uint16_t ms; 00217 00218 numCommands = *addr++; // Number of commands to follow 00219 while(numCommands--) { // For each command... 00220 writecommand(*addr++); // Read, issue command 00221 numArgs = *addr++; // Number of args to follow 00222 ms = numArgs & DELAY; // If hibit set, delay follows args 00223 numArgs &= ~DELAY; // Mask out delay bit 00224 while(numArgs--) { // For each argument... 00225 writedata(*addr++); // Read, issue argument 00226 } 00227 00228 if(ms) { 00229 ms = *addr++; // Read post-command delay time (ms) 00230 if(ms == 255) ms = 500; // If 255, delay for 500 ms 00231 wait_ms(ms); 00232 } 00233 } 00234 } 00235 00236 00237 // Initialization code common to both 'B' and 'R' type displays 00238 void Adafruit_ST7735::commonInit(uint8_t *cmdList) 00239 { 00240 00241 colstart = rowstart = 0; // May be overridden in init func 00242 00243 _rs = 1; 00244 chipDisable(); 00245 00246 // use default SPI format 00247 spi_port.format(8,3); 00248 spi_port.frequency(24000000); // Lets try 48MHz 00249 00250 // toggle RST low to reset; CS low so it'll listen to us 00251 chipEnable(); 00252 _rst = 1; 00253 wait_ms(50); 00254 _rst = 0; 00255 wait_ms(50); 00256 _rst = 1; 00257 wait_ms(50); 00258 00259 if(cmdList) commandList(cmdList); 00260 } 00261 00262 00263 // Initialization for ST7735B screens 00264 void Adafruit_ST7735::initB(void) 00265 { 00266 commonInit(Bcmd); 00267 } 00268 00269 00270 // Initialization for ST7735R screens (green or red tabs) 00271 void Adafruit_ST7735::initR(uint8_t options) 00272 { 00273 commonInit(Rcmd1); 00274 if(options == INITR_GREENTAB) { 00275 commandList(Rcmd2green); 00276 colstart = 2; 00277 rowstart = 1; 00278 } else if(options == INITR_144GREENTAB) { 00279 commandList(Rcmd2green144); 00280 colstart = 2; 00281 rowstart = 1; 00282 } else { 00283 // colstart, rowstart left at default '0' values 00284 commandList(Rcmd2red); 00285 } 00286 commandList(Rcmd3); 00287 } 00288 00289 void Adafruit_ST7735::backlight( uint8_t setting ) 00290 { 00291 _bl = setting; 00292 } 00293 00294 void Adafruit_ST7735::writeString( int x, int row, char * str, int flag ){ 00295 if( flag == NORMAL ){ 00296 setCursor( x, row * 10 ); 00297 setTextColor( BLACK, WHITE ); 00298 printf("%s",str); 00299 } else { 00300 setCursor( x, row * 10 ); 00301 setTextColor( WHITE, BLACK ); 00302 printf("%s",str); 00303 } 00304 } 00305 00306 void Adafruit_ST7735::writeString( int x, int row, char * str, int flag, char size ){ 00307 setTextSize(size); 00308 if( flag == NORMAL ){ 00309 setCursor( x, row*8 ); 00310 setTextColor( BLACK, WHITE ); 00311 printf("%s",str); 00312 } else { 00313 setCursor( x, row*8 ); 00314 setTextColor( WHITE, RED ); 00315 printf("%s",str); 00316 } 00317 } 00318 00319 00320 void Adafruit_ST7735::setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, 00321 uint8_t y1) 00322 { 00323 00324 writecommand(ST7735_CASET); // Column addr set 00325 writedata(0x00); 00326 writedata(x0+colstart); // XSTART 00327 writedata(0x00); 00328 writedata(x1+colstart); // XEND 00329 00330 writecommand(ST7735_RASET); // Row addr set 00331 writedata(0x00); 00332 writedata(y0+rowstart); // YSTART 00333 writedata(0x00); 00334 writedata(y1+rowstart); // YEND 00335 00336 writecommand(ST7735_RAMWR); // write to RAM 00337 } 00338 00339 00340 void Adafruit_ST7735::fillScreen(uint16_t color) 00341 { 00342 00343 uint8_t x, y, hi = color >> 8, lo = color; 00344 00345 setAddrWindow(0, 0, _width-1, _height-1); 00346 00347 _rs = 1; 00348 chipEnable(); 00349 00350 for(y=_height; y>0; y--) { 00351 for(x=_width; x>0; x--) { 00352 spi_port.write( hi ); 00353 spi_port.write( lo ); 00354 } 00355 } 00356 00357 chipDisable(); 00358 } 00359 00360 00361 void Adafruit_ST7735::pushColor(uint16_t color) 00362 { 00363 _rs = 1; 00364 chipEnable(); 00365 00366 spi_port.write( color >> 8 ); 00367 spi_port.write( color ); 00368 chipDisable(); 00369 } 00370 00371 00372 void Adafruit_ST7735::drawPixel(int16_t x, int16_t y, uint16_t color) 00373 { 00374 00375 if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; 00376 00377 setAddrWindow(x,y,x+1,y+1); 00378 00379 _rs = 1; 00380 chipEnable(); 00381 00382 spi_port.write( color >> 8 ); 00383 spi_port.write( color ); 00384 00385 chipDisable(); 00386 } 00387 00388 00389 void Adafruit_ST7735::drawFastVLine(int16_t x, int16_t y, int16_t h, 00390 uint16_t color) 00391 { 00392 00393 // Rudimentary clipping 00394 if((x >= _width) || (y >= _height)) return; 00395 if((y+h-1) >= _height) h = _height-y; 00396 setAddrWindow(x, y, x, y+h-1); 00397 00398 uint8_t hi = color >> 8, lo = color; 00399 _rs = 1; 00400 chipEnable(); 00401 while (h--) { 00402 spi_port.write( hi ); 00403 spi_port.write( lo ); 00404 } 00405 chipDisable(); 00406 } 00407 00408 00409 void Adafruit_ST7735::drawFastHLine(int16_t x, int16_t y, int16_t w, 00410 uint16_t color) 00411 { 00412 00413 // Rudimentary clipping 00414 if((x >= _width) || (y >= _height)) return; 00415 if((x+w-1) >= _width) w = _width-x; 00416 setAddrWindow(x, y, x+w-1, y); 00417 00418 uint8_t hi = color >> 8, lo = color; 00419 _rs = 1; 00420 chipEnable(); 00421 while (w--) { 00422 spi_port.write( hi ); 00423 spi_port.write( lo ); 00424 } 00425 chipDisable(); 00426 } 00427 00428 00429 // fill a rectangle 00430 void Adafruit_ST7735::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, 00431 uint16_t color) 00432 { 00433 00434 // rudimentary clipping (drawChar w/big text requires this) 00435 if((x >= _width) || (y >= _height)) return; 00436 if((x + w - 1) >= _width) w = _width - x; 00437 if((y + h - 1) >= _height) h = _height - y; 00438 00439 setAddrWindow(x, y, x+w-1, y+h-1); 00440 00441 uint8_t hi = color >> 8, lo = color; 00442 _rs = 1; 00443 chipEnable(); 00444 for(y=h; y>0; y--) { 00445 for(x=w; x>0; x--) { 00446 spi_port.write( hi ); 00447 spi_port.write( lo ); 00448 } 00449 } 00450 00451 chipDisable(); 00452 } 00453 00454 00455 // fill a rectangle 00456 void Adafruit_ST7735::bitmap(int16_t x, int16_t y, int16_t w, int16_t h, 00457 const unsigned char *map ) 00458 { 00459 00460 // rudimentary clipping (drawChar w/big text requires this) 00461 if((x >= _width) || (y >= _height)) return; 00462 if((x + w - 1) >= _width) w = _width - x; 00463 if((y + h - 1) >= _height) h = _height - y; 00464 00465 setAddrWindow(x, y, x+w-1, y+h-1); 00466 00467 _rs = 1; 00468 chipEnable(); 00469 for(y=0; y<h; y++) { 00470 for(x=0; x<w; x++) { 00471 spi_port.write( map[ y*w*2 + x*2 ] ); 00472 spi_port.write( map[ y*w*2 + x*2 + 1] ); 00473 } 00474 } 00475 chipDisable(); 00476 } 00477 00478 // fill a rectangle 00479 void Adafruit_ST7735::bitmapBW(int16_t x, int16_t y, const unsigned char *map, int16_t w, int16_t h, 00480 int16_t foreground, int16_t background ) 00481 { 00482 char dw, dh, xx, yy; 00483 00484 char fgA = foreground >> 8; 00485 char fgB = foreground & 0xFF; 00486 00487 char bgA = background >> 8; 00488 char bgB = background & 0xFF; 00489 00490 dw = w; 00491 dh = h; 00492 00493 // rudimentary clipping (drawChar w/big text requires this) 00494 // out of screen 00495 if((x >= _width) || (y >= _height)) return; 00496 00497 00498 if((x + w - 1) >= _width){ // positive clipping 00499 dw = _width - x; 00500 setAddrWindow(x, y, _width-1, y+h-1); 00501 } else if((y + h - 1) >= _height){ 00502 dh = _height - y; 00503 setAddrWindow(x, y, x+w-1, _height-1); 00504 } else if( x < 0 ){ // negative clipping 00505 setAddrWindow(0, y, x+w-1, y+h-1); 00506 } else { 00507 setAddrWindow(x, y, x+w-1, y+h-1); 00508 } 00509 00510 _rs = 1; 00511 chipEnable(); 00512 for(yy=0; yy<dh; yy++) { 00513 for(xx=0; xx<dw; xx++) { 00514 if( xx+x >= 0){ 00515 if( map[ (yy*w +xx)/8 ] & ( 1<<(xx%8) ) ){ 00516 spi_port.write( fgA ); 00517 spi_port.write( fgB ); 00518 } else { 00519 spi_port.write( bgA ); 00520 spi_port.write( bgB ); 00521 } 00522 } 00523 } 00524 } 00525 chipDisable(); 00526 } 00527 00528 // Pass 8-bit (each) R,G,B, get back 16-bit packed color 00529 uint16_t Adafruit_ST7735::Color565(uint8_t r, uint8_t g, uint8_t b) 00530 { 00531 return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); 00532 } 00533 00534 00535 #define MADCTL_MY 0x80 00536 #define MADCTL_MX 0x40 00537 #define MADCTL_MV 0x20 00538 #define MADCTL_ML 0x10 00539 #define MADCTL_RGB 0x08 00540 #define MADCTL_MH 0x04 00541 00542 void Adafruit_ST7735::setRotation(uint8_t m) 00543 { 00544 00545 writecommand(ST7735_MADCTL); 00546 rotation = m % 4; // can't be higher than 3 00547 switch (rotation) { 00548 case 0: 00549 writedata(MADCTL_MX | MADCTL_MY | MADCTL_RGB); 00550 _width = ST7735_TFTWIDTH; 00551 _height = ST7735_TFTHEIGHT; 00552 break; 00553 case 1: 00554 writedata(MADCTL_MY | MADCTL_MV | MADCTL_RGB); 00555 _width = ST7735_TFTHEIGHT; 00556 _height = ST7735_TFTWIDTH; 00557 break; 00558 case 2: 00559 writedata(MADCTL_RGB); 00560 _width = ST7735_TFTWIDTH; 00561 _height = ST7735_TFTHEIGHT; 00562 break; 00563 case 3: 00564 writedata(MADCTL_MX | MADCTL_MV | MADCTL_RGB); 00565 _width = ST7735_TFTHEIGHT; 00566 _height = ST7735_TFTWIDTH; 00567 break; 00568 } 00569 } 00570 00571 00572 void Adafruit_ST7735::invertDisplay(boolean i) 00573 { 00574 writecommand(i ? ST7735_INVON : ST7735_INVOFF); 00575 }
Generated on Thu Jul 14 2022 05:40:27 by 1.7.2