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.
Adafruit_ILI9341.cpp
00001 /*************************************************** 00002 This is our GFX example for the Adafruit ILI9341 Breakout and Shield 00003 ----> http://www.adafruit.com/products/1651 00004 Check out the links above for our tutorials and wiring diagrams 00005 These displays use SPI to communicate, 4 or 5 pins are required to 00006 interface (RST is optional) 00007 Adafruit invests time and resources providing this open source code, 00008 please support Adafruit and open-source hardware by purchasing 00009 products from Adafruit! 00010 Written by Limor Fried/Ladyada for Adafruit Industries. 00011 MIT license, all text above must be included in any redistribution 00012 ****************************************************/ 00013 /* 00014 Ported to mbed by James Kidd 00015 */ 00016 #include <stdint.h> 00017 #include <Adafruit_GFX.h> 00018 #include "Adafruit_ILI9341.h" 00019 #include "mbed.h" 00020 #include "PinNames.h" 00021 #include "BurstSPI.h" 00022 00023 Adafruit_ILI9341::Adafruit_ILI9341(PinName DC, PinName CS, PinName RST) : Adafruit_GFX(ILI9341_TFTWIDTH,ILI9341_TFTHEIGHT) { 00024 _pins.rst = RST; 00025 _pins.cs = CS; 00026 _pins.dc = DC; 00027 _pins.miso = SPI_MISO; 00028 _pins.mosi = SPI_MOSI; 00029 _pins.sclk = SPI_SCK; 00030 hwSPI = true; 00031 } 00032 00033 00034 inline void Adafruit_ILI9341::spiwrite(uint16_t c) { 00035 00036 //Serial.print("0x"); Serial.print(c, HEX); Serial.print(", "); 00037 LcdSPI->write(c); 00038 //LcdSPI->fastWrite(c >> 8); 00039 //LcdSPI->fastWrite(c); 00040 } 00041 void Adafruit_ILI9341::writecommand(uint8_t c) { 00042 00043 LcdSPI->format(8,3); 00044 LcdSPI->setFormat(); 00045 Pins[PIN_DC]->write(0); 00046 if(Pins[PIN_SCE] > 0) 00047 Pins[PIN_SCE]->write(0); 00048 LcdSPI->write(c); 00049 //spiwrite(c); 00050 if(Pins[PIN_SCE] > 0) 00051 Pins[PIN_SCE]->write(1); 00052 LcdSPI->format(16,3); 00053 LcdSPI->setFormat(); 00054 } 00055 00056 void Adafruit_ILI9341::writedata(uint16_t c) { 00057 00058 LcdSPI->format(8,3); 00059 LcdSPI->setFormat(); 00060 Pins[PIN_DC]->write(1); 00061 if(Pins[PIN_SCE] > 0) 00062 Pins[PIN_SCE]->write(0); 00063 LcdSPI->write(c); 00064 //spiwrite(c); 00065 if(Pins[PIN_SCE] > 0) 00066 Pins[PIN_SCE]->write(1); 00067 LcdSPI->format(16,3); 00068 LcdSPI->setFormat(); 00069 } 00070 00071 void Adafruit_ILI9341::commandList(uint8_t *addr) { 00072 00073 /*uint8_t numCommands, numArgs; 00074 uint16_t ms; 00075 00076 numCommands = pgm_read_byte(addr++); // Number of commands to follow 00077 while(numCommands--) { // For each command... 00078 writecommand(pgm_read_byte(addr++)); // Read, issue command 00079 numArgs = pgm_read_byte(addr++); // Number of args to follow 00080 ms = numArgs & DELAY; // If hibit set, delay follows args 00081 numArgs &= ~DELAY; // Mask out delay bit 00082 while(numArgs--) { // For each argument... 00083 writedata(pgm_read_byte(addr++)); // Read, issue argument 00084 } 00085 00086 if(ms) { 00087 ms = pgm_read_byte(addr++); // Read post-command delay time (ms) 00088 if(ms == 255) ms = 500; // If 255, delay for 500 ms 00089 wait_ms(ms); 00090 } 00091 }*/ 00092 } 00093 void Adafruit_ILI9341::begin(void) { 00094 LcdSPI = new BurstSPI(_pins.mosi,_pins.miso,_pins.sclk); 00095 LcdSPI->format(LCD_SPI_BITS, LCD_SPI_MODE); 00096 LcdSPI->frequency(LCD_FREQ); 00097 LcdSPI->setFormat(); 00098 Pins = new DigitalOut*[3]; 00099 Pins[PIN_RST] = new DigitalOut(_pins.rst); 00100 Pins[PIN_SCE] = new DigitalOut(_pins.cs); 00101 Pins[PIN_DC] = new DigitalOut(_pins.dc); 00102 00103 00104 00105 if (Pins[PIN_RST] > 0) { 00106 Pins[PIN_RST]->write(0); 00107 } 00108 Pins[PIN_DC]->write(0); 00109 Pins[PIN_SCE]->write(0); 00110 00111 // toggle RST low to reset 00112 if (Pins[PIN_RST] > 0) { 00113 Pins[PIN_RST]->write(1); 00114 wait_ms(5); 00115 Pins[PIN_RST]->write(0); 00116 wait_ms(20); 00117 Pins[PIN_RST]->write(1); 00118 wait_ms(150); 00119 } 00120 00121 /* 00122 uint8_t x = readcommand8(ILI9341_RDMODE); 00123 Serial.print("\nDisplay Power Mode: 0x"); Serial.println(x, HEX); 00124 x = readcommand8(ILI9341_RDMADCTL); 00125 Serial.print("\nMADCTL Mode: 0x"); Serial.println(x, HEX); 00126 x = readcommand8(ILI9341_RDPIXFMT); 00127 Serial.print("\nPixel Format: 0x"); Serial.println(x, HEX); 00128 x = readcommand8(ILI9341_RDIMGFMT); 00129 Serial.print("\nImage Format: 0x"); Serial.println(x, HEX); 00130 x = readcommand8(ILI9341_RDSELFDIAG); 00131 Serial.print("\nSelf Diagnostic: 0x"); Serial.println(x, HEX); 00132 */ 00133 //if(cmdList) commandList(cmdList); 00134 00135 if (hwSPI) spi_begin(); 00136 writecommand(0xEF); 00137 writedata(0x03); 00138 writedata(0x80); 00139 writedata(0x02); 00140 00141 writecommand(0xCF); 00142 writedata(0x00); 00143 writedata(0XC1); 00144 writedata(0X30); 00145 00146 writecommand(0xED); 00147 writedata(0x64); 00148 writedata(0x03); 00149 writedata(0X12); 00150 writedata(0X81); 00151 00152 writecommand(0xE8); 00153 writedata(0x85); 00154 writedata(0x00); 00155 writedata(0x78); 00156 00157 writecommand(0xCB); 00158 writedata(0x39); 00159 writedata(0x2C); 00160 writedata(0x00); 00161 writedata(0x34); 00162 writedata(0x02); 00163 00164 writecommand(0xF7); 00165 writedata(0x20); 00166 00167 writecommand(0xEA); 00168 writedata(0x00); 00169 writedata(0x00); 00170 00171 writecommand(ILI9341_PWCTR1); //Power control 00172 writedata(0x23); //VRH[5:0] 00173 00174 writecommand(ILI9341_PWCTR2); //Power control 00175 writedata(0x10); //SAP[2:0];BT[3:0] 00176 00177 writecommand(ILI9341_VMCTR1); //VCM control 00178 writedata(0x3e); //¶Ô±È¶Èµ÷½Ú 00179 writedata(0x28); 00180 00181 writecommand(ILI9341_VMCTR2); //VCM control2 00182 writedata(0x86); //-- 00183 00184 writecommand(ILI9341_MADCTL); // Memory Access Control 00185 writedata(0x48); 00186 00187 writecommand(ILI9341_PIXFMT); 00188 writedata(0x55); 00189 00190 writecommand(ILI9341_FRMCTR1); 00191 writedata(0x00); 00192 writedata(0x18); 00193 00194 writecommand(ILI9341_DFUNCTR); // Display Function Control 00195 writedata(0x08); 00196 writedata(0x82); 00197 writedata(0x27); 00198 00199 writecommand(0xF2); // 3Gamma Function Disable 00200 writedata(0x00); 00201 00202 writecommand(ILI9341_GAMMASET); //Gamma curve selected 00203 writedata(0x01); 00204 00205 writecommand(ILI9341_GMCTRP1); //Set Gamma 00206 writedata(0x0F); 00207 writedata(0x31); 00208 writedata(0x2B); 00209 writedata(0x0C); 00210 writedata(0x0E); 00211 writedata(0x08); 00212 writedata(0x4E); 00213 writedata(0xF1); 00214 writedata(0x37); 00215 writedata(0x07); 00216 writedata(0x10); 00217 writedata(0x03); 00218 writedata(0x0E); 00219 writedata(0x09); 00220 writedata(0x00); 00221 00222 writecommand(ILI9341_GMCTRN1); //Set Gamma 00223 writedata(0x00); 00224 writedata(0x0E); 00225 writedata(0x14); 00226 writedata(0x03); 00227 writedata(0x11); 00228 writedata(0x07); 00229 writedata(0x31); 00230 writedata(0xC1); 00231 writedata(0x48); 00232 writedata(0x08); 00233 writedata(0x0F); 00234 writedata(0x0C); 00235 writedata(0x31); 00236 writedata(0x36); 00237 writedata(0x0F); 00238 00239 writecommand(ILI9341_SLPOUT); //Exit Sleep 00240 if (hwSPI) spi_end(); 00241 wait_ms(120); 00242 if (hwSPI) spi_begin(); 00243 writecommand(ILI9341_DISPON); //Display on 00244 if (hwSPI) spi_end(); 00245 00246 } 00247 00248 00249 void Adafruit_ILI9341::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, 00250 uint16_t y1) { 00251 writecommand(ILI9341_CASET); // Column addr set 00252 writedata(x0 >> 8); 00253 writedata(x0 & 0xFF); // XSTART 00254 writedata(x1 >> 8); 00255 writedata(x1 & 0xFF); // XEND 00256 00257 writecommand(ILI9341_PASET); // Row addr set 00258 writedata(y0>>8); 00259 writedata(y0); // YSTART 00260 writedata(y1>>8); 00261 writedata(y1); // YEND 00262 00263 writecommand(ILI9341_RAMWR); // write to RAM 00264 } 00265 00266 00267 void Adafruit_ILI9341::pushColor(uint16_t color) { 00268 if (hwSPI) spi_begin(); 00269 Pins[PIN_DC]->write(1); 00270 Pins[PIN_SCE]->write(0); 00271 //digitalWrite(_dc, HIGH); 00272 //*dcport |= dcpinmask; 00273 //digitalWrite(_cs, LOW); 00274 //*csport &= ~cspinmask; 00275 00276 //spiwrite(color >> 8); 00277 spiwrite(color); 00278 Pins[PIN_SCE]->write(1); 00279 //*csport |= cspinmask; 00280 //digitalWrite(_cs, HIGH); 00281 if (hwSPI) spi_end(); 00282 } 00283 uint16_t buf[25][33]; 00284 void Adafruit_ILI9341::drawPixel(int16_t x, int16_t y, uint16_t color) { 00285 00286 if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; 00287 00288 if (hwSPI) spi_begin(); 00289 setAddrWindow(x,y,x+1,y+1); 00290 00291 //digitalWrite(_dc, HIGH); 00292 Pins[PIN_DC]->write(1); 00293 Pins[PIN_SCE]->write(0); 00294 00295 //*dcport |= dcpinmask; 00296 //digitalWrite(_cs, LOW); 00297 //*csport &= ~cspinmask; 00298 00299 //spiwrite(color >> 8); 00300 spiwrite(color); 00301 //LcdSPI->fastWrite(color); 00302 Pins[PIN_SCE]->write(1); 00303 //*csport |= cspinmask; 00304 //digitalWrite(_cs, HIGH); 00305 if (hwSPI) spi_end(); 00306 } 00307 00308 00309 void Adafruit_ILI9341::drawFastVLine(int16_t x, int16_t y, int16_t h, 00310 uint16_t color) { 00311 00312 // Rudimentary clipping 00313 if((x >= _width) || (y >= _height)) return; 00314 00315 if((y+h-1) >= _height) 00316 h = _height-y; 00317 00318 if (hwSPI) spi_begin(); 00319 setAddrWindow(x, y, x, y+h-1); 00320 00321 uint8_t hi = color >> 8, lo = color; 00322 00323 //*dcport |= dcpinmask; 00324 //digitalWrite(_dc, HIGH); 00325 //*csport &= ~cspinmask; 00326 //digitalWrite(_cs, LOW); 00327 Pins[PIN_DC]->write(1); 00328 Pins[PIN_SCE]->write(0); 00329 00330 while (h--) { 00331 LcdSPI->fastWrite(color); 00332 //spiwrite(color); 00333 //spiwrite(hi); 00334 //spiwrite(lo); 00335 } 00336 Pins[PIN_SCE]->write(1); 00337 //*csport |= cspinmask; 00338 //digitalWrite(_cs, HIGH); 00339 if (hwSPI) spi_end(); 00340 LcdSPI->clearRX(); 00341 } 00342 00343 00344 void Adafruit_ILI9341::drawFastHLine(int16_t x, int16_t y, int16_t w, 00345 uint16_t color) { 00346 00347 // Rudimentary clipping 00348 if((x >= _width) || (y >= _height)) return; 00349 if((x+w-1) >= _width) w = _width-x; 00350 if (hwSPI) spi_begin(); 00351 setAddrWindow(x, y, x+w-1, y); 00352 00353 uint8_t hi = color >> 8, lo = color; 00354 //*dcport |= dcpinmask; 00355 //*csport &= ~cspinmask; 00356 Pins[PIN_DC]->write(1); 00357 Pins[PIN_SCE]->write(0); 00358 //digitalWrite(_dc, HIGH); 00359 //digitalWrite(_cs, LOW); 00360 while (w--) { 00361 //spiwrite(color); 00362 LcdSPI->fastWrite(color); 00363 //spiwrite(hi); 00364 //spiwrite(lo); 00365 } 00366 Pins[PIN_SCE]->write(1); 00367 //*csport |= cspinmask; 00368 //digitalWrite(_cs, HIGH); 00369 if (hwSPI) spi_end(); 00370 LcdSPI->clearRX(); 00371 } 00372 00373 void Adafruit_ILI9341::fillScreen(uint16_t color) { 00374 fillRect(0, 0, _width, _height, color); 00375 } 00376 00377 00378 00379 // fill a rectangle 00380 void Adafruit_ILI9341::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, 00381 uint16_t color) { 00382 00383 // rudimentary clipping (drawChar w/big text requires this) 00384 if((x >= _width) || (y >= _height)) return; 00385 if((x + w - 1) >= _width) w = _width - x; 00386 if((y + h - 1) >= _height) h = _height - y; 00387 00388 if (hwSPI) spi_begin(); 00389 setAddrWindow(x, y, x+w-1, y+h-1); 00390 00391 uint8_t hi = color >> 8, lo = color; 00392 //LcdSPI->format(16, LCD_SPI_MODE); 00393 //LcdSPI->setFormat(); 00394 //*dcport |= dcpinmask; 00395 //digitalWrite(_dc, HIGH); 00396 //*csport &= ~cspinmask; 00397 //digitalWrite(_cs, LOW); 00398 Pins[PIN_DC]->write(1); 00399 Pins[PIN_SCE]->write(0); 00400 int32_t cnt; 00401 for(cnt = w*h;cnt > 0;cnt--){ 00402 LcdSPI->fastWrite(color); 00403 //spiwrite(hi); 00404 //spiwrite(color); 00405 //spiwrite(color); 00406 // LcdSPI->clearRX(); 00407 } 00408 /*for(y=h; y>0; y--) { 00409 for(x=w; x>0; x--) { 00410 //LcdSPI->fastWrite(color); 00411 //LcdSPI->write(hi); 00412 //LcdSPI->write(lo); 00413 spiwrite(hi); 00414 spiwrite(lo); 00415 } 00416 }*/ 00417 00418 //digitalWrite(_cs, HIGH); 00419 Pins[PIN_SCE]->write(1); 00420 //*csport |= cspinmask; 00421 if (hwSPI) spi_end(); 00422 00423 //wait_ms(30); 00424 LcdSPI->clearRX(); 00425 //LcdSPI->format(LCD_SPI_BITS, LCD_SPI_MODE); 00426 //LcdSPI->setFormat(); 00427 } 00428 00429 00430 // Pass 8-bit (each) R,G,B, get back 16-bit packed color 00431 uint16_t Adafruit_ILI9341::color565(uint8_t r, uint8_t g, uint8_t b) { 00432 return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); 00433 } 00434 00435 00436 #define MADCTL_MY 0x80 00437 #define MADCTL_MX 0x40 00438 #define MADCTL_MV 0x20 00439 #define MADCTL_ML 0x10 00440 #define MADCTL_RGB 0x00 00441 #define MADCTL_BGR 0x08 00442 #define MADCTL_MH 0x04 00443 00444 void Adafruit_ILI9341::setRotation(uint8_t m) { 00445 00446 if (hwSPI) spi_begin(); 00447 writecommand(ILI9341_MADCTL); 00448 rotation = m % 4; // can't be higher than 3 00449 switch (rotation) { 00450 case 0: 00451 writedata(MADCTL_MX | MADCTL_BGR); 00452 _width = ILI9341_TFTWIDTH; 00453 _height = ILI9341_TFTHEIGHT; 00454 break; 00455 case 1: 00456 writedata(MADCTL_MV | MADCTL_BGR); 00457 _width = ILI9341_TFTHEIGHT; 00458 _height = ILI9341_TFTWIDTH; 00459 break; 00460 case 2: 00461 writedata(MADCTL_MY | MADCTL_BGR); 00462 _width = ILI9341_TFTWIDTH; 00463 _height = ILI9341_TFTHEIGHT; 00464 break; 00465 case 3: 00466 writedata(MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR); 00467 _width = ILI9341_TFTHEIGHT; 00468 _height = ILI9341_TFTWIDTH; 00469 break; 00470 } 00471 if (hwSPI) spi_end(); 00472 } 00473 00474 00475 void Adafruit_ILI9341::invertDisplay(bool i) { 00476 if (hwSPI) spi_begin(); 00477 writecommand(i ? ILI9341_INVON : ILI9341_INVOFF); 00478 if (hwSPI) spi_end(); 00479 } 00480 00481 00482 00483 uint8_t Adafruit_ILI9341::spiread(void) { 00484 //LcdSPI->clearRX(); 00485 uint8_t r = 0; 00486 r = LcdSPI->write(0); 00487 return r; 00488 00489 } 00490 00491 00492 00493 uint8_t Adafruit_ILI9341::readdata(void) { 00494 Pins[PIN_DC]->write(1); 00495 Pins[PIN_SCE]->write(0); 00496 //digitalWrite(_dc, HIGH); 00497 //digitalWrite(_cs, LOW); 00498 uint8_t r = spiread(); 00499 //digitalWrite(_cs, HIGH); 00500 Pins[PIN_SCE]->write(1); 00501 return r; 00502 } 00503 00504 00505 uint8_t Adafruit_ILI9341::readcommand8(uint8_t c, uint8_t index) { 00506 if (hwSPI) spi_begin(); 00507 LcdSPI->format(8, LCD_SPI_MODE); 00508 00509 Pins[PIN_DC]->write(0); 00510 Pins[PIN_SCE]->write(0); 00511 //digitalWrite(_dc, LOW); // command 00512 //digitalWrite(_cs, LOW); 00513 spiwrite(0xD9); // woo sekret command? 00514 Pins[PIN_DC]->write(1); 00515 //digitalWrite(_dc, HIGH); // data 00516 spiwrite(0x10 + index); 00517 //digitalWrite(_cs, HIGH); 00518 Pins[PIN_SCE]->write(1); 00519 00520 Pins[PIN_DC]->write(0); 00521 Pins[PIN_SCE]->write(0); 00522 //digitalWrite(_dc, LOW); 00523 //digitalWrite(_sclk, LOW); 00524 //digitalWrite(_cs, LOW); 00525 spiwrite(c); 00526 Pins[PIN_DC]->write(1); 00527 //digitalWrite(_dc, HIGH); 00528 uint8_t r = spiread(); 00529 Pins[PIN_SCE]->write(1); 00530 //digitalWrite(_cs, HIGH); 00531 if (hwSPI) spi_end(); 00532 00533 LcdSPI->format(LCD_SPI_BITS, LCD_SPI_MODE); 00534 return r; 00535 }
Generated on Tue Jul 19 2022 09:34:37 by
