ILI9340 Library based on the Arduino version from Adafruit. It has been tested with a custom STM32F103C8 board.
Porting of the ILI9340 Library from Adafruit. It has been tested on a custom board based on a STM32F103C8 microcontroller.
Please, see the Wiki page on how to use the library
Adafruit_ILI9340.cpp
- Committer:
- gmoralis
- Date:
- 2014-12-17
- Revision:
- 2:effcedd42f1b
- Parent:
- 1:5f8309157018
File content as of revision 2:effcedd42f1b:
/*************************************************** This is an Arduino Library for the Adafruit 2.2" SPI display. This library works with the Adafruit 2.2" TFT Breakout w/SD card ----> http://www.adafruit.com/products/1480 Check out the links above for our tutorials and wiring diagrams These displays use SPI to communicate, 4 or 5 pins are required to interface (RST is optional) Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. MIT license, all text above must be included in any redistribution ****************************************************/ // Modified for mbed // by Georgios Moralis #include "mbed.h" #include "Adafruit_ILI9340.h" #include "stdint.h" #define OSET_BIT(dpin) dpin->write(1) #define OCLEAR_BIT(dpin) dpin->write(0) #define digitalWrite(dpin,value) ((value==0)?dpin->write(0):dpin->write(1)) #define digitalRead(dpin) (dpin->read()) // Single constructor either for software or hardware SPI Adafruit_ILI9340::Adafruit_ILI9340(SPI *defspi) : Adafruit_GFX(ILI9340_TFTWIDTH, ILI9340_TFTHEIGHT) { hwSPI = defspi; } void Adafruit_ILI9340::setMISO(DigitalIn *gport) { misoport = gport; } void Adafruit_ILI9340::setMOSI(DigitalOut *gport) { mosiport = gport; } void Adafruit_ILI9340::setCLK(DigitalOut *gport) { clkport = gport; } void Adafruit_ILI9340::setRST(DigitalOut *gport) { rstport = gport; } void Adafruit_ILI9340::setCS(DigitalOut *gport) { csport = gport; } void Adafruit_ILI9340::setDC(DigitalOut *gport) { dcport = gport; } void Adafruit_ILI9340::spiwrite(uint8_t c) { //Serial.print("0x"); Serial.print(c, HEX); Serial.print(", "); if (hwSPI) { hwSPI->write(c); } else { // Fast SPI bitbang swiped from LPD8806 library for(uint8_t bit = 0x80; bit; bit >>= 1) { if(c & bit) { OSET_BIT(mosiport); } else { OCLEAR_BIT(mosiport); } OSET_BIT(clkport); OCLEAR_BIT(clkport); } } } void Adafruit_ILI9340::writecommand(uint8_t c) { OCLEAR_BIT(dcport); if (!hwSPI) OCLEAR_BIT(clkport); OCLEAR_BIT(csport); spiwrite(c); OSET_BIT(csport); } void Adafruit_ILI9340::writedata(uint8_t c) { OSET_BIT(dcport); if (!hwSPI) OCLEAR_BIT(clkport); OCLEAR_BIT(csport); spiwrite(c); OSET_BIT(csport); } // Rather than a bazillion writecommand() and writedata() calls, screen // initialization commands and arguments are organized in these tables // stored in PROGMEM. The table may look bulky, but that's mostly the // formatting -- storage-wise this is hundreds of bytes more compact // than the equivalent code. Companion function follows. #define DELAY 0x80 // Companion code to the above tables. Reads and issues // a series of LCD commands stored in PROGMEM byte array. void Adafruit_ILI9340::commandList(uint8_t *addr) { uint8_t numCommands, numArgs; uint16_t ms; numCommands = pgm_read_byte(addr++); // Number of commands to follow while(numCommands--) { // For each command... writecommand(pgm_read_byte(addr++)); // Read, issue command numArgs = pgm_read_byte(addr++); // Number of args to follow ms = numArgs & DELAY; // If hibit set, delay follows args numArgs &= ~DELAY; // Mask out delay bit while(numArgs--) { // For each argument... writedata(pgm_read_byte(addr++)); // Read, issue argument } if(ms) { ms = pgm_read_byte(addr++); // Read post-command delay time (ms) if(ms == 255) ms = 500; // If 255, delay for 500 ms wait_ms(ms); } } } void Adafruit_ILI9340::begin(void) { digitalWrite(rstport, LOW); if(hwSPI) { hwSPI->frequency(16000000); } else { OCLEAR_BIT(clkport); OCLEAR_BIT(mosiport); } // toggle RST low to reset digitalWrite(rstport, HIGH); wait_ms(5); digitalWrite(rstport, LOW); wait_ms(20); digitalWrite(rstport, HIGH); wait_ms(150); /* uint8_t x = readcommand8(ILI9340_RDMODE); Serial.print("\nDisplay Power Mode: 0x"); Serial.println(x, HEX); x = readcommand8(ILI9340_RDMADCTL); Serial.print("\nMADCTL Mode: 0x"); Serial.println(x, HEX); x = readcommand8(ILI9340_RDPIXFMT); Serial.print("\nPixel Format: 0x"); Serial.println(x, HEX); x = readcommand8(ILI9340_RDIMGFMT); Serial.print("\nImage Format: 0x"); Serial.println(x, HEX); x = readcommand8(ILI9340_RDSELFDIAG); Serial.print("\nSelf Diagnostic: 0x"); Serial.println(x, HEX); */ //if(cmdList) commandList(cmdList); writecommand(0xEF); writedata(0x03); writedata(0x80); writedata(0x02); writecommand(0xCF); writedata(0x00); writedata(0XC1); writedata(0X30); writecommand(0xED); writedata(0x64); writedata(0x03); writedata(0X12); writedata(0X81); writecommand(0xE8); writedata(0x85); writedata(0x00); writedata(0x78); writecommand(0xCB); writedata(0x39); writedata(0x2C); writedata(0x00); writedata(0x34); writedata(0x02); writecommand(0xF7); writedata(0x20); writecommand(0xEA); writedata(0x00); writedata(0x00); writecommand(ILI9340_PWCTR1); //Power control writedata(0x23); //VRH[5:0] writecommand(ILI9340_PWCTR2); //Power control writedata(0x10); //SAP[2:0];BT[3:0] writecommand(ILI9340_VMCTR1); //VCM control writedata(0x3e); // writedata(0x28); writecommand(ILI9340_VMCTR2); //VCM control2 writedata(0x86); //-- writecommand(ILI9340_MADCTL); // Memory Access Control writedata(ILI9340_MADCTL_MX | ILI9340_MADCTL_BGR); writecommand(ILI9340_PIXFMT); writedata(0x55); writecommand(ILI9340_FRMCTR1); writedata(0x00); writedata(0x18); writecommand(ILI9340_DFUNCTR); // Display Function Control writedata(0x08); writedata(0x82); writedata(0x27); writecommand(0xF2); // 3Gamma Function Disable writedata(0x00); writecommand(ILI9340_GAMMASET); //Gamma curve selected writedata(0x01); writecommand(ILI9340_GMCTRP1); //Set Gamma writedata(0x0F); writedata(0x31); writedata(0x2B); writedata(0x0C); writedata(0x0E); writedata(0x08); writedata(0x4E); writedata(0xF1); writedata(0x37); writedata(0x07); writedata(0x10); writedata(0x03); writedata(0x0E); writedata(0x09); writedata(0x00); writecommand(ILI9340_GMCTRN1); //Set Gamma writedata(0x00); writedata(0x0E); writedata(0x14); writedata(0x03); writedata(0x11); writedata(0x07); writedata(0x31); writedata(0xC1); writedata(0x48); writedata(0x08); writedata(0x0F); writedata(0x0C); writedata(0x31); writedata(0x36); writedata(0x0F); writecommand(ILI9340_SLPOUT); //Exit Sleep wait_ms(120); writecommand(ILI9340_DISPON); //Display on } void Adafruit_ILI9340::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { writecommand(ILI9340_CASET); // Column addr set writedata(x0 >> 8); writedata(x0 & 0xFF); // XSTART writedata(x1 >> 8); writedata(x1 & 0xFF); // XEND writecommand(ILI9340_PASET); // Row addr set writedata(y0>>8); writedata(y0); // YSTART writedata(y1>>8); writedata(y1); // YEND writecommand(ILI9340_RAMWR); // write to RAM } void Adafruit_ILI9340::pushColor(uint16_t color) { OSET_BIT(dcport); OCLEAR_BIT(csport); spiwrite(color >> 8); spiwrite(color); OSET_BIT(csport); } void Adafruit_ILI9340::drawPixel(int16_t x, int16_t y, uint16_t color) { if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; setAddrWindow(x,y,x+1,y+1); OSET_BIT(dcport); OCLEAR_BIT(csport); spiwrite(color >> 8); spiwrite(color); OSET_BIT(csport); } void Adafruit_ILI9340::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { // Rudimentary clipping if((x >= _width) || (y >= _height)) return; if((y+h-1) >= _height) h = _height-y; setAddrWindow(x, y, x, y+h-1); uint8_t hi = color >> 8, lo = color; OSET_BIT(dcport); OCLEAR_BIT(csport); while (h--) { spiwrite(hi); spiwrite(lo); } OSET_BIT(csport); } void Adafruit_ILI9340::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { // Rudimentary clipping if((x >= _width) || (y >= _height)) return; if((x+w-1) >= _width) w = _width-x; setAddrWindow(x, y, x+w-1, y); uint8_t hi = color >> 8, lo = color; OSET_BIT(dcport); OCLEAR_BIT(csport); while (w--) { spiwrite(hi); spiwrite(lo); } OSET_BIT(csport); } void Adafruit_ILI9340::fillScreen(uint16_t color) { fillRect(0, 0, _width, _height, color); } // fill a rectangle void Adafruit_ILI9340::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { // rudimentary clipping (drawChar w/big text requires this) if((x >= _width) || (y >= _height)) return; if((x + w - 1) >= _width) w = _width - x; if((y + h - 1) >= _height) h = _height - y; setAddrWindow(x, y, x+w-1, y+h-1); uint8_t hi = color >> 8, lo = color; OSET_BIT(dcport); //digitalWrite(_dc, HIGH); OCLEAR_BIT(csport); //digitalWrite(_cs, LOW); for(y=h; y>0; y--) { for(x=w; x>0; x--) { spiwrite(hi); spiwrite(lo); } } //digitalWrite(_cs, HIGH); OSET_BIT(csport); } // Pass 8-bit (each) R,G,B, get back 16-bit packed color uint16_t Adafruit_ILI9340::Color565(uint8_t r, uint8_t g, uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); } void Adafruit_ILI9340::setRotation(uint8_t m) { writecommand(ILI9340_MADCTL); rotation = m % 4; // can't be higher than 3 switch (rotation) { case 0: writedata(ILI9340_MADCTL_MX | ILI9340_MADCTL_BGR); _width = ILI9340_TFTWIDTH; _height = ILI9340_TFTHEIGHT; break; case 1: writedata(ILI9340_MADCTL_MV | ILI9340_MADCTL_BGR); _width = ILI9340_TFTHEIGHT; _height = ILI9340_TFTWIDTH; break; case 2: writedata(ILI9340_MADCTL_MY | ILI9340_MADCTL_BGR); _width = ILI9340_TFTWIDTH; _height = ILI9340_TFTHEIGHT; break; case 3: writedata(ILI9340_MADCTL_MV | ILI9340_MADCTL_MY | ILI9340_MADCTL_MX | ILI9340_MADCTL_BGR); _width = ILI9340_TFTHEIGHT; _height = ILI9340_TFTWIDTH; break; } } void Adafruit_ILI9340::invertDisplay(char i) { writecommand(i ? ILI9340_INVON : ILI9340_INVOFF); } ////////// stuff not actively being used, but kept for posterity uint8_t Adafruit_ILI9340::spiread(void) { uint8_t r = 0; if (hwSPI) { r = hwSPI->write(0); } else { for (uint8_t i=0; i<8; i++) { digitalWrite(clkport, LOW); digitalWrite(clkport, HIGH); r <<= 1; if (digitalRead(misoport)) r |= 0x1; } } return r; } uint8_t Adafruit_ILI9340::readdata(void) { digitalWrite(dcport, HIGH); digitalWrite(csport, LOW); uint8_t r = spiread(); digitalWrite(csport, HIGH); return r; } uint8_t Adafruit_ILI9340::readcommand8(uint8_t c) { digitalWrite(dcport, LOW); if (!hwSPI) digitalWrite(clkport, LOW); digitalWrite(csport, LOW); spiwrite(c); digitalWrite(dcport, HIGH); uint8_t r = spiread(); digitalWrite(csport, HIGH); return r; } /* uint16_t Adafruit_ILI9340::readcommand16(uint8_t c) { digitalWrite(_dc, LOW); if (_cs) digitalWrite(_cs, LOW); spiwrite(c); pinMode(_sid, INPUT); // input! uint16_t r = spiread(); r <<= 8; r |= spiread(); if (_cs) digitalWrite(_cs, HIGH); pinMode(_sid, OUTPUT); // back to output return r; } uint32_t Adafruit_ILI9340::readcommand32(uint8_t c) { digitalWrite(_dc, LOW); if (_cs) digitalWrite(_cs, LOW); spiwrite(c); pinMode(_sid, INPUT); // input! dummyclock(); dummyclock(); uint32_t r = spiread(); r <<= 8; r |= spiread(); r <<= 8; r |= spiread(); r <<= 8; r |= spiread(); if (_cs) digitalWrite(_cs, HIGH); pinMode(_sid, OUTPUT); // back to output return r; } */