James Kidd / Adafruit_ILI9341

Dependents:   ili9341_test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Adafruit_ILI9341.cpp Source File

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 }