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
Diff: Adafruit_ILI9340.cpp
- Revision:
- 0:0bf2453a67ba
- Child:
- 1:5f8309157018
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adafruit_ILI9340.cpp Tue Nov 04 08:08:46 2014 +0000 @@ -0,0 +1,553 @@ +/*************************************************** + 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 SET_BIT(dpin) dpin->write(1) +#define CLEAR_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) { + SET_BIT(mosiport); + } else { + + CLEAR_BIT(mosiport); + } + SET_BIT(clkport); + CLEAR_BIT(clkport); + } + } +} + + +void Adafruit_ILI9340::writecommand(uint8_t c) { + CLEAR_BIT(dcport); + if (!hwSPI) + CLEAR_BIT(clkport); + + CLEAR_BIT(csport); + + spiwrite(c); + + SET_BIT(csport); +} + + +void Adafruit_ILI9340::writedata(uint8_t c) { + SET_BIT(dcport); + if (!hwSPI) + CLEAR_BIT(clkport); + + CLEAR_BIT(csport); + + + spiwrite(c); + + + SET_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 { + CLEAR_BIT(clkport); + CLEAR_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) { + + SET_BIT(dcport); + + CLEAR_BIT(csport); + + spiwrite(color >> 8); + spiwrite(color); + + SET_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); + + + SET_BIT(dcport); + + CLEAR_BIT(csport); + + spiwrite(color >> 8); + spiwrite(color); + + SET_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; + + SET_BIT(dcport); + + CLEAR_BIT(csport); + + + while (h--) { + spiwrite(hi); + spiwrite(lo); + } + SET_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; + SET_BIT(dcport); + CLEAR_BIT(csport); + + while (w--) { + spiwrite(hi); + spiwrite(lo); + } + SET_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; + + SET_BIT(dcport); + //digitalWrite(_dc, HIGH); + CLEAR_BIT(csport); + //digitalWrite(_cs, LOW); + + for(y=h; y>0; y--) { + for(x=w; x>0; x--) { + spiwrite(hi); + spiwrite(lo); + } + } + //digitalWrite(_cs, HIGH); + SET_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; + } + + */ +