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 /*************************************************** 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 "ST7735.h" 00021 00022 Serial output1(USBTX, USBRX); 00023 00024 //uint16_t table[1028][18] __attribute__((section("AHBSRAM0"))); 00025 00026 inline uint16_t swapcolor(uint16_t x) { 00027 return (x << 11) | (x & 0x07E0) | (x >> 11); 00028 } 00029 00030 // Constructor 00031 ST7735::ST7735(PinName mosi, PinName miso, PinName sck, PinName cs, PinName rs, PinName rst) 00032 : lcdPort(mosi, miso, sck), _cs(cs), _rs(rs), _rst(rst), GFX(ST7735_TFTWIDTH_128, ST7735_TFTHEIGHT_160) 00033 { } 00034 00035 00036 void ST7735::writecommand(uint8_t c) 00037 { 00038 _rs = 0; 00039 _cs = 0; 00040 lcdPort.write( c ); 00041 _cs = 1; 00042 } 00043 00044 00045 void ST7735::writedata(uint8_t c) 00046 { 00047 _rs = 1; 00048 _cs = 0; 00049 lcdPort.write( c ); 00050 00051 _cs = 1; 00052 } 00053 00054 00055 // Rather than a bazillion writecommand() and writedata() calls, screen 00056 // initialization commands and arguments are organized in these tables 00057 // stored in PROGMEM. The table may look bulky, but that's mostly the 00058 // formatting -- storage-wise this is hundreds of bytes more compact 00059 // than the equivalent code. Companion function follows. 00060 #define DELAY 0x80 00061 static unsigned char 00062 Bcmd[] = { // Initialization commands for 7735B screens 00063 18, // 18 commands in list: 00064 ST7735_SWRESET, DELAY, // 1: Software reset, no args, w/delay 00065 50, // 50 ms delay 00066 ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, no args, w/delay 00067 255, // 255 = 500 ms delay 00068 ST7735_COLMOD , 1+DELAY, // 3: Set color mode, 1 arg + delay: 00069 0x05, // 16-bit color 00070 10, // 10 ms delay 00071 ST7735_FRMCTR1, 3+DELAY, // 4: Frame rate control, 3 args + delay: 00072 0x00, // fastest refresh 00073 0x06, // 6 lines front porch 00074 0x03, // 3 lines back porch 00075 10, // 10 ms delay 00076 ST7735_MADCTL , 1 , // 5: Memory access ctrl (directions), 1 arg: 00077 0x08, // Row addr/col addr, bottom to top refresh 00078 ST7735_DISSET5, 2 , // 6: Display settings #5, 2 args, no delay: 00079 0x15, // 1 clk cycle nonoverlap, 2 cycle gate 00080 // rise, 3 cycle osc equalize 00081 0x02, // Fix on VTL 00082 ST7735_INVCTR , 1 , // 7: Display inversion control, 1 arg: 00083 0x0, // Line inversion 00084 ST7735_PWCTR1 , 2+DELAY, // 8: Power control, 2 args + delay: 00085 0x02, // GVDD = 4.7V 00086 0x70, // 1.0uA 00087 10, // 10 ms delay 00088 ST7735_PWCTR2 , 1 , // 9: Power control, 1 arg, no delay: 00089 0x05, // VGH = 14.7V, VGL = -7.35V 00090 ST7735_PWCTR3 , 2 , // 10: Power control, 2 args, no delay: 00091 0x01, // Opamp current small 00092 0x02, // Boost frequency 00093 ST7735_VMCTR1 , 2+DELAY, // 11: Power control, 2 args + delay: 00094 0x3C, // VCOMH = 4V 00095 0x38, // VCOML = -1.1V 00096 10, // 10 ms delay 00097 ST7735_PWCTR6 , 2 , // 12: Power control, 2 args, no delay: 00098 0x11, 0x15, 00099 ST7735_GMCTRP1,16 , // 13: Magical unicorn dust, 16 args, no delay: 00100 0x09, 0x16, 0x09, 0x20, // (seriously though, not sure what 00101 0x21, 0x1B, 0x13, 0x19, // these config values represent) 00102 0x17, 0x15, 0x1E, 0x2B, 00103 0x04, 0x05, 0x02, 0x0E, 00104 ST7735_GMCTRN1,16+DELAY, // 14: Sparkles and rainbows, 16 args + delay: 00105 0x0B, 0x14, 0x08, 0x1E, // (ditto) 00106 0x22, 0x1D, 0x18, 0x1E, 00107 0x1B, 0x1A, 0x24, 0x2B, 00108 0x06, 0x06, 0x02, 0x0F, 00109 10, // 10 ms delay 00110 ST7735_CASET , 4 , // 15: Column addr set, 4 args, no delay: 00111 0x00, 0x02, // XSTART = 2 00112 0x00, 0x81, // XEND = 129 00113 ST7735_RASET , 4 , // 16: Row addr set, 4 args, no delay: 00114 0x00, 0x02, // XSTART = 1 00115 0x00, 0x81, // XEND = 160 00116 ST7735_NORON , DELAY, // 17: Normal display on, no args, w/delay 00117 10, // 10 ms delay 00118 ST7735_DISPON , DELAY, // 18: Main screen turn on, no args, w/delay 00119 255 }, // 255 = 500 ms delay 00120 00121 Rcmd1[] = { // Init for 7735R, part 1 (red or green tab) 00122 15, // 15 commands in list: 00123 ST7735_SWRESET, DELAY, // 1: Software reset, 0 args, w/delay 00124 150, // 150 ms delay 00125 ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, 0 args, w/delay 00126 255, // 500 ms delay 00127 ST7735_FRMCTR1, 3 , // 3: Frame rate ctrl - normal mode, 3 args: 00128 0x01, 0x2C, 0x2D, // Rate = fosc/(1x2+40) * (LINE+2C+2D) 00129 ST7735_FRMCTR2, 3 , // 4: Frame rate control - idle mode, 3 args: 00130 0x01, 0x2C, 0x2D, // Rate = fosc/(1x2+40) * (LINE+2C+2D) 00131 ST7735_FRMCTR3, 6 , // 5: Frame rate ctrl - partial mode, 6 args: 00132 0x01, 0x2C, 0x2D, // Dot inversion mode 00133 0x01, 0x2C, 0x2D, // Line inversion mode 00134 ST7735_INVCTR , 1 , // 6: Display inversion ctrl, 1 arg, no delay: 00135 0x07, // No inversion 00136 ST7735_PWCTR1 , 3 , // 7: Power control, 3 args, no delay: 00137 0xA2, 00138 0x02, // -4.6V 00139 0x84, // AUTO mode 00140 ST7735_PWCTR2 , 1 , // 8: Power control, 1 arg, no delay: 00141 0xC5, // VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD 00142 ST7735_PWCTR3 , 2 , // 9: Power control, 2 args, no delay: 00143 0x0A, // Opamp current small 00144 0x00, // Boost frequency 00145 ST7735_PWCTR4 , 2 , // 10: Power control, 2 args, no delay: 00146 0x8A, // BCLK/2, Opamp current small & Medium low 00147 0x2A, 00148 ST7735_PWCTR5 , 2 , // 11: Power control, 2 args, no delay: 00149 0x8A, 0xEE, 00150 ST7735_VMCTR1 , 1 , // 12: Power control, 1 arg, no delay: 00151 0x0E, 00152 ST7735_INVOFF , 0 , // 13: Don't invert display, no args, no delay 00153 ST7735_MADCTL , 1 , // 14: Memory access control (directions), 1 arg: 00154 0xC0, // row addr/col addr, bottom to top refresh 00155 ST7735_COLMOD , 1 , // 15: set color mode, 1 arg, no delay: 00156 0x05 }, // 16-bit color 00157 00158 Rcmd2green[] = { // Init for 7735R, part 2 (green tab only) 00159 2, // 2 commands in list: 00160 ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay: 00161 0x00, 0x02, // XSTART = 0 00162 0x00, 0x7F+0x02, // XEND = 127 00163 ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay: 00164 0x00, 0x01, // XSTART = 0 00165 0x00, 0x9F+0x01 }, // XEND = 159 00166 Rcmd2red[] = { // Init for 7735R, part 2 (red tab only) 00167 2, // 2 commands in list: 00168 ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay: 00169 0x00, 0x00, // XSTART = 0 00170 0x00, 0x7F, // XEND = 127 00171 ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay: 00172 0x00, 0x00, // XSTART = 0 00173 0x00, 0x9F }, // XEND = 159 00174 00175 Rcmd2green144[] = { // Init for 7735R, part 2 (green 1.44 tab) 00176 2, // 2 commands in list: 00177 ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay: 00178 0x00, 0x00, // XSTART = 0 00179 0x00, 0x7F, // XEND = 127 00180 ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay: 00181 0x00, 0x00, // XSTART = 0 00182 0x00, 0x7F }, // XEND = 127 00183 00184 Rcmd2green160x80[] = { // Init for 7735R, part 2 (mini 160x80) 00185 2, // 2 commands in list: 00186 ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay: 00187 0x00, 0x00, // XSTART = 0 00188 0x00, 0x7F, // XEND = 79 00189 ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay: 00190 0x00, 0x00, // XSTART = 0 00191 0x00, 0x9F+0x01 }, // XEND = 159 00192 00193 Rcmd3[] = { // Init for 7735R, part 3 (red or green tab) 00194 4, // 4 commands in list: 00195 ST7735_GMCTRP1, 16 , // 1: Magical unicorn dust, 16 args, no delay: 00196 0x02, 0x1c, 0x07, 0x12, 00197 0x37, 0x32, 0x29, 0x2d, 00198 0x29, 0x25, 0x2B, 0x39, 00199 0x00, 0x01, 0x03, 0x10, 00200 ST7735_GMCTRN1, 16 , // 2: Sparkles and rainbows, 16 args, no delay: 00201 0x03, 0x1d, 0x07, 0x06, 00202 0x2E, 0x2C, 0x29, 0x2D, 00203 0x2E, 0x2E, 0x37, 0x3F, 00204 0x00, 0x00, 0x02, 0x10, 00205 ST7735_NORON , DELAY, // 3: Normal display on, no args, w/delay 00206 10, // 10 ms delay 00207 ST7735_DISPON , DELAY, // 4: Main screen turn on, no args w/delay 00208 100 }; // 100 ms delay 00209 00210 00211 // Companion code to the above tables. Reads and issues 00212 // a series of LCD commands stored in byte array. 00213 void ST7735::commandList(uint8_t *addr) 00214 { 00215 00216 uint8_t numCommands, numArgs; 00217 uint16_t ms; 00218 00219 numCommands = *addr++; // Number of commands to follow 00220 while(numCommands--) { // For each command... 00221 writecommand(*addr++); // Read, issue command 00222 numArgs = *addr++; // Number of args to follow 00223 ms = numArgs & DELAY; // If hibit set, delay follows args 00224 numArgs &= ~DELAY; // Mask out delay bit 00225 while(numArgs--) { // For each argument... 00226 writedata(*addr++); // Read, issue argument 00227 } 00228 00229 if(ms) { 00230 ms = *addr++; // Read post-command delay time (ms) 00231 if(ms == 255) ms = 500; // If 255, delay for 500 ms 00232 wait_ms(ms); 00233 } 00234 } 00235 } 00236 00237 00238 // Initialization code common to both 'B' and 'R' type displays 00239 void ST7735::commonInit(uint8_t *cmdList) 00240 { 00241 00242 colstart = rowstart = 0; // May be overridden in init func 00243 00244 _rs = 1; 00245 _cs = 1; 00246 00247 // use default SPI format 00248 lcdPort.format(8,0); 00249 //lcdPort.frequency(16000000); // Lets try 4MHz 00250 lcdPort.frequency(64000000); // Lets try 4MHz 00251 00252 // toggle RST low to reset; CS low so it'll listen to us 00253 _cs = 0; 00254 _rst = 1; 00255 wait_ms(500); 00256 _rst = 0; 00257 wait_ms(500); 00258 _rst = 1; 00259 wait_ms(500); 00260 00261 if(cmdList) commandList(cmdList); 00262 } 00263 00264 00265 // Initialization for ST7735B screens 00266 void ST7735::initB(void) 00267 { 00268 commonInit(Bcmd); 00269 } 00270 00271 00272 // Initialization for ST7735R screens (green or red tabs) 00273 void ST7735::initR(uint8_t options) { 00274 commonInit(Rcmd1); 00275 if(options == INITR_GREENTAB) { 00276 commandList(Rcmd2green); 00277 colstart = 2; 00278 rowstart = 1; 00279 } else if(options == INITR_144GREENTAB) { 00280 _height = ST7735_TFTHEIGHT_128; 00281 _width = ST7735_TFTWIDTH_128; 00282 commandList(Rcmd2green144); 00283 colstart = 2; 00284 rowstart = 3; 00285 } else if(options == INITR_MINI160x80) { 00286 _height = ST7735_TFTHEIGHT_160; 00287 _width = ST7735_TFTWIDTH_80; 00288 commandList(Rcmd2green160x80); 00289 colstart = 24; 00290 rowstart = 0; 00291 } else if(options == INITR_MINI160x80_RS) { 00292 _height = ST7735_TFTHEIGHT_160; 00293 _width = ST7735_TFTWIDTH_80; 00294 commandList(Rcmd2green160x80); 00295 writecommand(1 ? ST7735_INVON : ST7735_INVOFF); 00296 colstart = 26; 00297 rowstart = 1; 00298 _tft_type = 2; 00299 } else { 00300 // colstart, rowstart left at default '0' values 00301 commandList(Rcmd2red); 00302 } 00303 commandList(Rcmd3); 00304 00305 // if black, change MADCTL color filter 00306 if (options == INITR_BLACKTAB) { 00307 writecommand(ST7735_MADCTL); 00308 writedata(0xC0); 00309 } 00310 00311 tabcolor = options; 00312 } 00313 00314 void ST7735::setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, 00315 uint8_t y1) 00316 { 00317 00318 writecommand(ST7735_CASET); // Column addr set 00319 writedata(0x00); 00320 writedata(x0+xstart); // XSTART 00321 writedata(0x00); 00322 writedata(x1+xstart); // XEND 00323 00324 writecommand(ST7735_RASET); // Row addr set 00325 writedata(0x00); 00326 writedata(y0+ystart); // YSTART 00327 writedata(0x00); 00328 writedata(y1+ystart); // YEND 00329 00330 writecommand(ST7735_RAMWR); // write to RAM 00331 } 00332 00333 void ST7735::pushColor(uint16_t color) 00334 { 00335 _rs = 1; 00336 _cs = 0; 00337 00338 lcdPort.write( color >> 8 ); 00339 lcdPort.write( color ); 00340 _cs = 1; 00341 } 00342 00343 00344 void ST7735::drawPixel(int16_t x, int16_t y, uint16_t color) 00345 { 00346 00347 if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; 00348 00349 setAddrWindow(x,y,x+1,y+1); 00350 00351 _rs = 1; 00352 _cs = 0; 00353 00354 lcdPort.write( color >> 8 ); 00355 lcdPort.write( color ); 00356 00357 _cs = 1; 00358 } 00359 00360 00361 void ST7735::drawFastVLine(int16_t x, int16_t y, int16_t h, 00362 uint16_t color) 00363 { 00364 00365 // Rudimentary clipping 00366 if((x >= _width) || (y >= _height)) return; 00367 if((y+h-1) >= _height) h = _height-y; 00368 setAddrWindow(x, y, x, y+h-1); 00369 00370 uint8_t hi = color >> 8, lo = color; 00371 _rs = 1; 00372 _cs = 0; 00373 while (h--) { 00374 lcdPort.write( hi ); 00375 lcdPort.write( lo ); 00376 } 00377 _cs = 1; 00378 } 00379 00380 00381 void ST7735::drawFastHLine(int16_t x, int16_t y, int16_t w, 00382 uint16_t color) 00383 { 00384 00385 // Rudimentary clipping 00386 if((x >= _width) || (y >= _height)) return; 00387 if((x+w-1) >= _width) w = _width-x; 00388 setAddrWindow(x, y, x+w-1, y); 00389 00390 uint8_t hi = color >> 8, lo = color; 00391 _rs = 1; 00392 _cs = 0; 00393 while (w--) { 00394 lcdPort.write( hi ); 00395 lcdPort.write( lo ); 00396 } 00397 _cs = 1; 00398 } 00399 00400 00401 00402 void ST7735::fillScreen(uint16_t color) 00403 { 00404 fillRect(-10, -10, _width+20, _height+20, color); 00405 } 00406 00407 00408 // fill a rectangle 00409 void ST7735::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, 00410 uint16_t color) 00411 { 00412 00413 // rudimentary clipping (drawChar w/big text requires this) 00414 if((x >= _width) || (y >= _height)) return; 00415 if((x + w - 1) >= _width) w = _width - x; 00416 if((y + h - 1) >= _height) h = _height - y; 00417 00418 setAddrWindow(x, y, x+w-1, y+h-1); 00419 00420 uint8_t hi = color >> 8, lo = color; 00421 _rs = 1; 00422 _cs = 0; 00423 for(y=h; y>0; y--) { 00424 for(x=w; x>0; x--) { 00425 lcdPort.write( hi ); 00426 lcdPort.write( lo ); 00427 } 00428 } 00429 00430 _cs = 1; 00431 } 00432 00433 00434 // Pass 8-bit (each) R,G,B, get back 16-bit packed color 00435 uint16_t ST7735::Color565(uint8_t r, uint8_t g, uint8_t b) 00436 { 00437 return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); 00438 } 00439 00440 // Pass 8-bit (each) R,G,B, get back 16-bit packed color 00441 char* ST7735::Color565string(uint8_t r, uint8_t g, uint8_t b) 00442 { 00443 uint16_t color; 00444 char colorString[4]; 00445 00446 color = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); 00447 00448 sprintf(colorString, "%04x", color); 00449 00450 //output1.printf("0x%04x : %s\n", color, colorString); 00451 00452 return colorString; 00453 //return "test"; 00454 } 00455 00456 00457 #define MADCTL_MY 0x80 00458 #define MADCTL_MX 0x40 00459 #define MADCTL_MV 0x20 00460 #define MADCTL_ML 0x10 00461 #define MADCTL_RGB 0x00 00462 #define MADCTL_BGR 0x08 00463 #define MADCTL_MH 0x04 00464 00465 void ST7735::setRotation(uint8_t m) { 00466 _orientation = m; 00467 writecommand(ST7735_MADCTL); 00468 rotation = m % 4; // can't be higher than 3 00469 switch (rotation) { 00470 case 0: 00471 if ((tabcolor == INITR_BLACKTAB) || (tabcolor == INITR_MINI160x80)) { 00472 writedata(MADCTL_MX | MADCTL_MY | MADCTL_RGB); 00473 } else if (tabcolor == INITR_MINI160x80_RS) { 00474 writedata(MADCTL_MX | MADCTL_MY | MADCTL_BGR); 00475 } else { 00476 writedata(MADCTL_MX | MADCTL_MY | MADCTL_BGR); 00477 } 00478 00479 if (tabcolor == INITR_144GREENTAB) { 00480 _height = ST7735_TFTHEIGHT_128; 00481 _width = ST7735_TFTWIDTH_128; 00482 } else if ((tabcolor == INITR_MINI160x80) || (tabcolor == INITR_MINI160x80_RS)) { 00483 _height = ST7735_TFTHEIGHT_160; 00484 _width = ST7735_TFTWIDTH_80; 00485 } else { 00486 _height = ST7735_TFTHEIGHT_160; 00487 _width = ST7735_TFTWIDTH_128; 00488 } 00489 xstart = colstart; 00490 ystart = rowstart; 00491 break; 00492 case 1: 00493 if ((tabcolor == INITR_BLACKTAB) || (tabcolor == INITR_MINI160x80)) { 00494 writedata(MADCTL_MY | MADCTL_MV | MADCTL_RGB); 00495 } else if (tabcolor == INITR_MINI160x80_RS) { 00496 writedata(MADCTL_MY | MADCTL_MV | MADCTL_BGR); 00497 } else { 00498 writedata(MADCTL_MY | MADCTL_MV | MADCTL_BGR); 00499 } 00500 00501 if (tabcolor == INITR_144GREENTAB) { 00502 _width = ST7735_TFTHEIGHT_128; 00503 _height = ST7735_TFTWIDTH_128; 00504 } else if ((tabcolor == INITR_MINI160x80) || (tabcolor == INITR_MINI160x80_RS)) { 00505 _width = ST7735_TFTHEIGHT_160; 00506 _height = ST7735_TFTWIDTH_80; 00507 } else { 00508 _width = ST7735_TFTHEIGHT_160; 00509 _height = ST7735_TFTWIDTH_128; 00510 } 00511 ystart = colstart; 00512 xstart = rowstart; 00513 break; 00514 case 2: 00515 if ((tabcolor == INITR_BLACKTAB) || (tabcolor == INITR_MINI160x80)) { 00516 writedata(MADCTL_RGB); 00517 } else if (tabcolor == INITR_MINI160x80_RS) { 00518 writedata(MADCTL_BGR); 00519 } else { 00520 writedata(MADCTL_BGR); 00521 } 00522 00523 if (tabcolor == INITR_144GREENTAB) { 00524 _height = ST7735_TFTHEIGHT_128; 00525 _width = ST7735_TFTWIDTH_128; 00526 } else if ((tabcolor == INITR_MINI160x80) || (tabcolor == INITR_MINI160x80_RS)) { 00527 _height = ST7735_TFTHEIGHT_160; 00528 _width = ST7735_TFTWIDTH_80; 00529 } else { 00530 _height = ST7735_TFTHEIGHT_160; 00531 _width = ST7735_TFTWIDTH_128; 00532 } 00533 xstart = colstart; 00534 ystart = rowstart; 00535 break; 00536 case 3: 00537 if ((tabcolor == INITR_BLACKTAB) || (tabcolor == INITR_MINI160x80)) { 00538 writedata(MADCTL_MX | MADCTL_MV | MADCTL_RGB); 00539 } else if (tabcolor == INITR_MINI160x80_RS) { 00540 writedata(MADCTL_MX | MADCTL_MV | MADCTL_BGR); 00541 } else { 00542 writedata(MADCTL_MX | MADCTL_MV | MADCTL_BGR); 00543 } 00544 00545 if (tabcolor == INITR_144GREENTAB) { 00546 _width = ST7735_TFTHEIGHT_128; 00547 _height = ST7735_TFTWIDTH_128; 00548 } else if ((tabcolor == INITR_MINI160x80) || (tabcolor == INITR_MINI160x80_RS)) { 00549 _width = ST7735_TFTHEIGHT_160; 00550 _height = ST7735_TFTWIDTH_80; 00551 } else { 00552 _width = ST7735_TFTHEIGHT_160; 00553 _height = ST7735_TFTWIDTH_128; 00554 } 00555 ystart = colstart; 00556 xstart = rowstart; 00557 break; 00558 } 00559 } 00560 00561 void ST7735::invertDisplay(boolean i) 00562 { 00563 writecommand(i ? ST7735_INVON : ST7735_INVOFF); 00564 } 00565 00566 void ST7735::DrawBMP(int offsetx, int offsety, FILE *Image) 00567 { 00568 uint32_t index = 0, width = 0, height = 0; 00569 int i=0, x, y, byteCour; 00570 00571 int fpOffset = ftell(Image); 00572 //output1.printf("current cursor : %02x\n", ftell(Image)); 00573 //output1.printf("first bytes bmp : %02x\n", fgetc(Image)); 00574 00575 /* Get bitmap data address offset */ 00576 fseek(Image, 10+fpOffset , SEEK_SET ); 00577 index = fgetc(Image); 00578 //output1.printf("index : 0x%02x ; ", index); 00579 00580 /* Read bitmap width */ 00581 fseek(Image, 18+fpOffset , SEEK_SET ); 00582 width = fgetc(Image); 00583 width += fgetc(Image)<<8; 00584 width += fgetc(Image)<<16; 00585 width += fgetc(Image)<<24; 00586 //output1.printf("width : %d ; ", width); 00587 00588 /* Read bitmap height */ 00589 fseek(Image, 22+fpOffset , SEEK_SET ); 00590 height = fgetc(Image); 00591 height += fgetc(Image)<<8; 00592 height += fgetc(Image)<<16; 00593 height += fgetc(Image)<<24; 00594 //output1.printf("height : %d\n", height); 00595 00596 fseek(Image, index+fpOffset , SEEK_SET ); 00597 00598 byteCour = fgetc(Image); 00599 byteCour += fgetc(Image)<<8; 00600 00601 for (y = height+offsety; offsety < y; y--) { 00602 setAddrWindow(offsetx, y, offsetx+width-1, y); 00603 _rs = 1; 00604 _cs = 0; 00605 00606 for (x = 0; x < width; x++) { 00607 if(x == width-1) fseek(Image, width%2, SEEK_CUR); 00608 00609 if(x <= width && y >= 0) { 00610 lcdPort.write(byteCour>>8); // one line 00611 lcdPort.write(byteCour); 00612 } 00613 _cs = 1; 00614 byteCour = fgetc(Image); 00615 byteCour += fgetc(Image)<<8; 00616 _cs = 0; 00617 } 00618 } 00619 _cs = 1; 00620 } 00621 00622 // use imageconverter565.exe to generate bitmap array and put it in bitmap.c 00623 void ST7735::DrawRam(unsigned int x, unsigned int y, unsigned int w, unsigned int h, int *Image) { 00624 unsigned int i,j; 00625 setAddrWindow(x, y, x+w-1, y+h); 00626 _rs = 1; 00627 _cs = 0; 00628 for (j = 0; j < h; j++) { //Lines 00629 for (i = 0; i < w; i++) { // copy pixel data to TFT 00630 lcdPort.write(*Image>>8); // one line 00631 lcdPort.write(*Image); 00632 *Image++; 00633 } 00634 } 00635 _cs = 1; 00636 } 00637 00638 void ST7735::DrawGIF(int offsetx, int offsety, FILE *Image) { 00639 00640 uint32_t width = 0, height = 0; 00641 uint16_t code, preCode, clearCode, endCode, sizePalette; 00642 uint8_t r, v, b, pxl, pxls[256]; 00643 int i, j; 00644 int fpOffset = ftell(Image); 00645 00646 // palette 00647 uint16_t table[750][17]; 00648 for(int i = 0; i < 750; i++) 00649 for(int j = 0; j < 17; j++) 00650 table[i][j] = NULL; 00651 00652 // Read bitmap width 00653 fseek(Image, 6+fpOffset , SEEK_SET ); 00654 width = fgetc(Image); 00655 width += fgetc(Image); 00656 //output1.printf("width : %d ; ", width); 00657 00658 // Read bitmap height 00659 fseek(Image, 8+fpOffset , SEEK_SET ); 00660 height = fgetc(Image); 00661 height += fgetc(Image); 00662 //output1.printf("height : %d\n", height); 00663 00664 // Get size of palette 00665 fseek(Image, 10+fpOffset , SEEK_SET ); 00666 sizePalette = fgetc(Image)<<5; 00667 sizePalette = ((uint8_t) sizePalette)>>5; 00668 sizePalette = pow(2, sizePalette+1.0); 00669 00670 // Get palette 00671 uint16_t palette[sizePalette]; 00672 fseek(Image, 13+fpOffset , SEEK_SET ); 00673 for(i=0; i < sizePalette; i++) { 00674 r = fgetc(Image); 00675 v = fgetc(Image); 00676 b = fgetc(Image); 00677 00678 // palette simple 00679 palette[i] = Color565(r, v, b); 00680 table[i][0] = 1;table[i][1] = i; 00681 } 00682 00683 preCode = i; 00684 table[i][0] = i; 00685 clearCode = i; 00686 table[i+1][0] = i+1; 00687 endCode = i+1; 00688 00689 // Find Image separator 00690 while(1) { 00691 pxl = fgetc(Image); 00692 if(0x2C == pxl) break; 00693 } 00694 00695 // Get minimal size of code 00696 fseek(Image, 9 , SEEK_CUR ); 00697 uint8_t sizeCode = fgetc(Image);sizeCode++; 00698 00699 // Get size of block 00700 uint8_t sizeBlock = fgetc(Image); 00701 output1.printf("taille du block : %d\n", sizeBlock); 00702 00703 setAddrWindow(offsetx, offsety, offsetx+width-1, offsety+height); 00704 _rs = 1; 00705 _cs = 0; 00706 00707 // image data 00708 uint16_t imgByte = fgetc(Image); 00709 int sizeImgByte = 8; 00710 int16_t index = sizePalette; 00711 for(i=0; i < sizeBlock; ) { 00712 00713 // ajout d'un octet pour le calcul du prochain code 00714 while(sizeImgByte < sizeCode) { 00715 pxl = fgetc(Image); 00716 i++; 00717 if(sizeBlock == 0xff && i == sizeBlock) { 00718 i = 0; 00719 sizeBlock = pxl; 00720 pxl = fgetc(Image); 00721 } 00722 imgByte = (pxl<<(sizeImgByte)) + bitExtracted(imgByte, sizeImgByte, 1); 00723 sizeImgByte += 8; 00724 } 00725 00726 // extraction du code 00727 code = bitExtracted(imgByte, sizeCode, 1); 00728 00729 //output1.printf(">%03x; %03x; %03x; ", code, preCode, index); 00730 00731 ////////////////////// 00732 // traitement image // 00733 ////////////////////// 00734 00735 if(code == clearCode) index = sizePalette; 00736 else if(code == endCode) break; 00737 else { 00738 00739 // sauf si premier code : chargement du "pixel string" du precode 00740 if(preCode != clearCode){ 00741 for(j=0; j < table[preCode][0];j++) 00742 pxls[j] = table[preCode][j+1]; 00743 } 00744 00745 // si code connu : 00746 if(code < index) { 00747 00748 for(int k=1; k <= table[code][0];k++) { 00749 if(k==1) pxls[j] = table[code][k]; 00750 00751 lcdPort.write((uint8_t) (palette[ table[code][k] ]>>8)); 00752 lcdPort.write((uint8_t) palette[ table[code][k] ]); 00753 } 00754 00755 for(int k=1; k <= j+1; k++) 00756 table[index][k] = pxls[k-1]; 00757 00758 table[index][0] = j+1; 00759 00760 00761 } else { 00762 00763 // add new stream pixel in palette and display 00764 pxl = pxls[0]; 00765 pxls[j] = pxl; 00766 for(int k=1; k <= j+1; k++) { 00767 table[index][k] = pxls[k-1]; 00768 00769 lcdPort.write((uint8_t) (palette[ pxls[k-1] ]>>8)); 00770 lcdPort.write((uint8_t) palette[ pxls[k-1] ]); 00771 00772 } 00773 table[index][0] = j+1; 00774 } 00775 00776 // clear buffer string 00777 for(int k=0; k < 256; k++) pxls[k] = 0; 00778 } 00779 00780 preCode = code; 00781 00782 // to compute next code 00783 sizeImgByte -= sizeCode; 00784 imgByte = bitExtracted(imgByte, sizeImgByte, sizeCode+1); 00785 00786 if( index == (pow(2, sizeCode*1.0)-1)) sizeCode++; 00787 00788 index++; 00789 } 00790 00791 _cs = 1; 00792 00793 } 00794 00795 void ST7735::DrawANI(int offsetx, int offsety, FILE *Anim, int frame) { 00796 00797 int i; 00798 char buf[32]; 00799 char sizeStr[12]; 00800 char *valExit = "error"; 00801 char namefile[32]; 00802 int size, offset = 0; 00803 00804 sprintf(namefile, "%d.bmp", frame); 00805 00806 while(!feof(Anim)) { 00807 for(i=0; i <= strlen(namefile); i++) buf[i] = fgetc(Anim); 00808 00809 if(!strcmp(buf, namefile)) { 00810 valExit = ""; 00811 break; 00812 } 00813 00814 fseek(Anim , 124+offset , SEEK_SET); 00815 for(i=0; i < 12; i++) sizeStr[i] = fgetc(Anim); 00816 //printf("size string: %s; octal: %d; dec.: %x\n", sizeStr, atoi(sizeStr), oct2dec(atoi(sizeStr)) ); 00817 00818 size = oct2dec(atoi(sizeStr)); 00819 if(offset % 512 != 0) offset += (size/512 + 2)*512; 00820 else offset += (size/512 + 1)*512; 00821 00822 fseek(Anim , offset , SEEK_SET); 00823 } 00824 00825 if(valExit == "error") { 00826 printf("file \"%s\" not find in tar\n", namefile); 00827 //return NULL; 00828 } else { 00829 fseek(Anim, offset+512 , SEEK_SET); 00830 00831 DrawBMP(offsetx, offsety, Anim); 00832 00833 //return 1; 00834 } 00835 00836 00837 } 00838 00839 void ST7735::scrollBmp(uint8_t top_fix_height, uint8_t bottom_fix_height, int _scroll_direction, int *bitmap) { 00840 unsigned int i, startOffset, endOffset;// line = 0; 00841 float a, b; 00842 00843 a = 7.7142*pow( 162.0-(top_fix_height+bottom_fix_height), -2.0 ); 00844 b = 8.0717*pow( 162.0-(top_fix_height+bottom_fix_height), -1.0 ); 00845 00846 if(!_orientation) _scroll_direction = !_scroll_direction; 00847 00848 if((_scroll_direction && _orientation == 2) || (!_scroll_direction && !_orientation)) { 00849 for (i = 0; i < 3248; i++) *bitmap++; 00850 } 00851 00852 if((!_scroll_direction && _orientation == 2) || (_scroll_direction && !_orientation)) { 00853 startOffset = top_fix_height; 00854 endOffset = bottom_fix_height+1; 00855 } else { 00856 startOffset = bottom_fix_height; 00857 endOffset = top_fix_height+1; 00858 } 00859 00860 if((_scroll_direction && _orientation == 2) || (!_scroll_direction && !_orientation)) setScrollDefinition(bottom_fix_height, top_fix_height+1, _scroll_direction); 00861 else setScrollDefinition(top_fix_height+1, bottom_fix_height, _scroll_direction); 00862 00863 for( int scroll = 1+startOffset; scroll <= 162-endOffset ; scroll++){ 00864 00865 VerticalScroll(scroll); 00866 00867 if(scroll >=(53) && scroll <=109) { 00868 if(_orientation == 0){ 00869 if(_scroll_direction) { 00870 drawFastHLine(0, 162-(scroll)-2, 80, ST7735_BLACK); 00871 00872 for (i = 0; i < 57; i++) { 00873 drawPixel(57+11-i, 162-(scroll)-2, *bitmap); 00874 *bitmap++; 00875 } 00876 } else { 00877 drawFastHLine(0, scroll-2, 80, ST7735_BLACK); 00878 00879 for (i = 0; i < 57; i++) { 00880 drawPixel(12+i, scroll-2, *bitmap); 00881 *bitmap--; 00882 } 00883 } 00884 } else if(_orientation == 2) { 00885 if(_scroll_direction) { 00886 drawFastHLine(0, 162-scroll-1, 80, ST7735_BLACK); 00887 00888 for (i = 0; i < 57; i++) { 00889 drawPixel(57+10-i,162-scroll-1, *bitmap); 00890 *bitmap--; 00891 } 00892 } else { 00893 drawFastHLine(0, scroll-1, 80, ST7735_BLACK); 00894 00895 for (i = 0; i < 57; i++) { 00896 drawPixel(11+i,scroll-1, *bitmap); 00897 *bitmap++; 00898 } 00899 } 00900 } 00901 } 00902 00903 float tempo = (a*scroll*scroll)-b*scroll+2.9408; 00904 wait_ms(tempo); 00905 //wait(0.1); 00906 } 00907 if(!_orientation) setRotation(0); 00908 VerticalScroll(0); 00909 } 00910 00911 int ST7735::oct2dec(int n) /* Function to convert octal to decimal */ 00912 { 00913 int decimal=0, i=0, rem; 00914 while (n!=0) 00915 { 00916 rem = n%10; 00917 n/=10; 00918 decimal += rem*pow(8.0,i); 00919 ++i; 00920 } 00921 return decimal; 00922 } 00923 00924 int ST7735::bitExtracted(int number, int k, int p) 00925 { 00926 return (((1 << k) - 1) & (number >> (p - 1))); 00927 } 00928 00929 void ST7735::makeTable(void) { 00930 remove("/sd/table.csv"); 00931 remove("/sd/pointers.csv"); 00932 FILE *table = fopen("/sd/table.csv", "w"); 00933 FILE *pointers = fopen("/sd/pointers.csv", "w"); 00934 fclose(table); 00935 fclose(pointers); 00936 } 00937 00938 uint16_t ST7735::readTable(unsigned int y, unsigned int x) { 00939 00940 FILE *table = fopen("/sd/table.csv", "r"); 00941 FILE *pointers = fopen("/sd/pointers.csv", "r"); 00942 char out[3]; 00943 char ptr[17]; 00944 00945 fseek(pointers , y*17 , SEEK_SET); 00946 //output1.printf("%d: ", y); 00947 for(int i=0; i < 17; i++) { 00948 ptr[i] = fgetc(pointers); 00949 //output1.printf("%c", ptr[i]); 00950 } 00951 //output1.printf("\n%s>>%d\n", ptr, atoi(ptr)); 00952 00953 // utiliser pointers 00954 //for(int i=0; i < y;) 00955 //if(fgetc(table) == 0x0A) i++; 00956 fseek(table , atoi(ptr) , SEEK_SET); 00957 00958 for(int i=0; i < x;) 00959 if(fgetc(table) == 0x3B) i++; 00960 00961 out[0] = fgetc(table); 00962 out[1] = fgetc(table); 00963 out[2] = fgetc(table); 00964 00965 //output1.printf("%s>>%x ", out, atoi(out)); 00966 00967 fclose(table); 00968 fclose(pointers); 00969 return atoi(out); 00970 } 00971 00972 void ST7735::addrowTable(uint16_t *row) { 00973 00974 int size; 00975 00976 FILE *table = fopen("/sd/table.csv", "r"); 00977 fseek(table , 0 , SEEK_END); 00978 size = ftell(table); 00979 fclose(table); 00980 00981 table = fopen("/sd/table.csv", "a"); 00982 for(int i = 0; i< row[0]+1; i++) 00983 fprintf(table, "%03d;", row[i]); 00984 fprintf(table, "\n"); 00985 00986 FILE *pointers = fopen("/sd/pointers.csv", "a"); 00987 fprintf(pointers, "%16d\n", size); 00988 00989 fclose(table); 00990 fclose(pointers); 00991 } 00992 00993 void ST7735::init_star(STAR* star, int i) 00994 { 00995 /* randomly init stars, generate them around the center of the screen */ 00996 00997 star->xpos = -10.0 + (20.0 * (rand()/(RAND_MAX+1.0))); 00998 star->ypos = -10.0 + (20.0 * (rand()/(RAND_MAX+1.0))); 00999 01000 star->xpos *= 3072.0; /*change viewpoint */ 01001 star->ypos *= 3072.0; 01002 01003 star->zpos = i; 01004 star->speed = 2 + (int)(2.0 * (rand()/(RAND_MAX+1.0))); 01005 01006 star->color = i*ST7735_WHITE >> 2; /*the closer to the viewer the brighter*/ 01007 } 01008 01009 void ST7735::DrawStarfield(int centerx, int centery, int acc, int color, int NbrsStars, int duration) 01010 { 01011 int i, j=0, tempx, tempy; 01012 STAR stars[NbrsStars]; 01013 Timer timerStars; 01014 01015 timerStars.start(); 01016 while(timerStars.read() < duration) { 01017 01018 j++; 01019 01020 // move and draw stars 01021 01022 for (i = 0; i < NbrsStars; i++) { 01023 tempx = (stars[i].xpos / stars[i].zpos) + centerx; 01024 tempy = (stars[i].ypos / stars[i].zpos) + centery; 01025 drawPixel(tempx,tempy, ST7735_BLACK); 01026 01027 01028 stars[i].zpos -= stars[i].speed*acc; 01029 01030 if (stars[i].zpos <= 0) { 01031 init_star(stars + i, i + 1); 01032 } 01033 01034 //compute 3D position 01035 tempx = (stars[i].xpos / stars[i].zpos) + centerx; 01036 tempy = (stars[i].ypos / stars[i].zpos) + centery; 01037 01038 if (tempx < 0 || tempx > _width - 1 || tempy < 0 || tempy > _height - 1) { //check if a star leaves the screen 01039 01040 init_star(stars + i, i + 1); 01041 continue; 01042 } 01043 01044 if(color) drawPixel(tempx,tempy,color); 01045 else drawPixel(tempx,tempy,stars[i].color); 01046 01047 } 01048 } 01049 01050 timerStars.stop(); 01051 } 01052 01053 void ST7735::setScrollDefinition(uint8_t top_fix_height, uint8_t bottom_fix_height, int _scroll_direction){ 01054 uint8_t scroll_height; 01055 scroll_height = _height - top_fix_height - bottom_fix_height; 01056 writecommand(ST7735_VSCRDEF); 01057 writedata(0x00); 01058 writedata(top_fix_height); 01059 writedata(0x00); 01060 writedata(scroll_height); 01061 writedata(0x00); 01062 writedata(bottom_fix_height); 01063 writecommand(ST7735_MADCTL); 01064 if(_scroll_direction){ 01065 if(_tft_type == 0){ 01066 writedata(0xD8); 01067 } 01068 if(_tft_type == 1){ 01069 writedata(0xD0); 01070 } 01071 if(_tft_type == 2){ 01072 writedata(0x18); 01073 } 01074 } 01075 else{ 01076 if(_tft_type == 0){ 01077 writedata(0xC8); 01078 } 01079 if(_tft_type == 1){ 01080 writedata(0xC0); 01081 } 01082 if(_tft_type == 2){ 01083 writedata(0x08); 01084 } 01085 } 01086 } 01087 void ST7735::VerticalScroll(uint8_t _vsp) { 01088 writecommand(ST7735_VSCRSADD); 01089 writedata(0x00); 01090 writedata(_vsp); 01091 } 01092 01093 //void ST7735::read_area(unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned char *buffer) { 01094 void ST7735::read_area(unsigned int x, unsigned int y, unsigned int w, unsigned int h) { 01095 // BEWARE ! 01096 // DOES NOT WORK CORRECTLY YET !!! 01097 int val; 01098 setAddrWindow2(x,y,w,h); 01099 writecommand(ST7735_RAMRD); // write to RAM 01100 _cs = 0; 01101 _rs = 1; 01102 lcdPort.write(0); /* Dummy read 1 */ 01103 01104 val = lcdPort.write(0); /* Read D8..D15 */ 01105 val <<= 8; 01106 val |= lcdPort.write(0); /* Read D0..D7 */ 01107 _cs = 1; 01108 output1.printf("%d ", val); 01109 01110 01111 01112 } 01113 01114 01115 void ST7735::setAddrWindow2(uint8_t x0, uint8_t y0, uint8_t x1, 01116 uint8_t y1) 01117 { 01118 01119 writecommand(ST7735_CASET); // Column addr set 01120 writedata(0x00); 01121 writedata(x0+xstart); // XSTART 01122 writedata(0x00); 01123 writedata(x1+xstart); // XEND 01124 01125 writecommand(ST7735_RASET); // Row addr set 01126 writedata(0x00); 01127 writedata(y0+ystart); // YSTART 01128 writedata(0x00); 01129 writedata(y1+ystart); // YEND 01130 01131 //writecommand(ST7735_RAMWR); // write to RAM 01132 } 01133 01134
Generated on Tue Jul 12 2022 15:05:43 by
1.7.2