Added new display module GREENTAB2 (3.3v compact blue board, 8 pin no SD card)

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Adafruit_ST7735.cpp Source File

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