A simple yet powerful library for controlling graphical displays. Multiple display controllers are supported using inheritance.
Dependents: mbed_rifletool Hexi_Bubble_Game Hexi_Catch-the-dot_Game Hexi_Acceleromagnetic_Synth
NOTE: This library is in beta right now. As far as I know, everything here works, but there are many features that are lacking so far. Most notably containers, button handling, and display drivers other than the SSD1306.
Diff: Drivers/ILI9341.cpp
- Revision:
- 1:f7003ec66a51
- Child:
- 2:bbfc18022ee5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Drivers/ILI9341.cpp Fri Mar 14 19:17:44 2014 +0000 @@ -0,0 +1,283 @@ +/* NeatGUI Library + * Copyright (c) 2013 Neil Thiessen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ILI9341.h" + +ILI9341::ILI9341(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc) : Display(240, 320), m_SPI(mosi, miso, sclk), m_CS(cs), m_DC(dc) +{ + //Set the control pins to a known state + m_CS = 1; + m_DC = 1; + + //Set the SPI format to 8-bit + m_SPI.format(8, 3); + + //Set the SPI frequency to 10MHz + m_SPI.frequency(10000000); +} + +bool ILI9341::open() +{ + writeCommand(0x01); + wait_ms(5); + + writeCommand(0xCF); + writeData8(0x00); + writeData8(0x8B); + writeData8(0X30); + + writeCommand(0xED); + writeData8(0x67); + writeData8(0x03); + writeData8(0X12); + writeData8(0X81); + + writeCommand(0xE8); + writeData8(0x85); + writeData8(0x10); + writeData8(0x7A); + + writeCommand(0xCB); + writeData8(0x39); + writeData8(0x2C); + writeData8(0x00); + writeData8(0x34); + writeData8(0x02); + + writeCommand(0xF7); + writeData8(0x20); + + writeCommand(0xEA); + writeData8(0x00); + writeData8(0x00); + + writeCommand(0xC0); /* Power control */ + writeData8(0x1B); /* VRH[5:0] */ + + writeCommand(0xC1); /* Power control */ + writeData8(0x10); /* SAP[2:0];BT[3:0] */ + + writeCommand(0xC5); /* VCM control */ + writeData8(0x3F); + writeData8(0x3C); + + writeCommand(0xC7); /* VCM control2 */ + writeData8(0XB7); + + writeCommand(0x36); /* Memory Access Control */ + writeData8(0x08); + + writeCommand(0x3A); + writeData8(0x55); + + writeCommand(0xB1); + writeData8(0x00); + writeData8(0x1B); + + writeCommand(0xB6); /* Display Function Control */ + writeData8(0x0A); + writeData8(0xA2); + + + writeCommand(0xF2); /* 3Gamma Function Disable */ + writeData8(0x00); + + writeCommand(0x26); /* Gamma curve selected */ + writeData8(0x01); + + writeCommand(0xE0); /* Set Gamma */ + writeData8(0x0F); + writeData8(0x2A); + writeData8(0x28); + writeData8(0x08); + writeData8(0x0E); + writeData8(0x08); + writeData8(0x54); + writeData8(0XA9); + writeData8(0x43); + writeData8(0x0A); + writeData8(0x0F); + writeData8(0x00); + writeData8(0x00); + writeData8(0x00); + writeData8(0x00); + + writeCommand(0XE1); /* Set Gamma */ + writeData8(0x00); + writeData8(0x15); + writeData8(0x17); + writeData8(0x07); + writeData8(0x11); + writeData8(0x06); + writeData8(0x2B); + writeData8(0x56); + writeData8(0x3C); + writeData8(0x05); + writeData8(0x10); + writeData8(0x0F); + writeData8(0x3F); + writeData8(0x3F); + writeData8(0x0F); + + writeCommand(0x11); /* Exit Sleep */ + wait_ms(120); + writeCommand(0x29); /* Display on */ + + //Probe for the ILI9341 using a Zero Length Transfer + /*if (!m_I2C.write(m_Addr, NULL, 0)) { + //Init sequence for 128x64 OLED module + writeCommand(CMD_DISPLAYOFF); + writeCommand(CMD_SETDISPLAYCLOCKDIV); + writeCommand(0x80); + writeCommand(CMD_SETMULTIPLEX); + writeCommand(0x3F); + writeCommand(CMD_SETDISPLAYOFFSET); + writeCommand(0x0); + writeCommand(CMD_SETSTARTLINE | 0x0); + writeCommand(CMD_CHARGEPUMP); + writeCommand(CMD_CHARGEPUMPON); + writeCommand(CMD_MEMORYMODE); + writeCommand(0x00); + writeCommand(CMD_SEGREMAP | 0x1); + writeCommand(CMD_COMSCANDEC); + writeCommand(CMD_SETCOMPINS); + writeCommand(0x12); + writeCommand(CMD_SETCONTRAST); + writeCommand(0xCF); + writeCommand(CMD_SETPRECHARGE); + writeCommand(0xF1); + writeCommand(CMD_SETVCOMDETECT); + writeCommand(0x40); + writeCommand(CMD_DISPLAYALLON_RESUME); + writeCommand(CMD_NORMALDISPLAY); + + //Return success + return true; + } else { + //Return failure + return false; + }*/ + + return true; +} + +void ILI9341::finalize() +{ + //Select low col 0, hi col 0, line 0 + //writeCommand(CMD_SETLOWCOLUMN | 0x0); + //writeCommand(CMD_SETHIGHCOLUMN | 0x0); + //writeCommand(CMD_SETSTARTLINE | 0x0); + + //Make sure the first byte in the buffer is the control byte + //m_Buffer[0] = CONTROL_DATA; + + //Write the buffer + //m_I2C.write(m_Addr, m_Buffer, 1025); +} + +Display::State ILI9341::state() +{ + //Return the base class's state + return Display::state(); +} + +void ILI9341::state(State s) +{ + //Check what the requested state is + if (s == Display::DISPLAY_ON) { + //Turn the display on + //writeCommand(CMD_DISPLAYON); + } else if (s == Display::DISPLAY_OFF) { + //Turn the display off + //writeCommand(CMD_DISPLAYOFF); + } + + //Update the base class + Display::state(s); +} + +void ILI9341::drawPixel(int x, int y, unsigned int c) +{ + //Range check the pixel + if ((x < 0) || (x >= width()) || (y < 0) || (y >= height())) + return; + + //TODO: Clean up this code!!! + + //Set the column + writeCommand(0x2A); + writeData16(x); + writeData16(x); + + //Set the page + writeCommand(0x2B); + writeData16(y); + writeData16(y); + + //Don't know what this does... + writeCommand(0x2C); + + //Woohoo, send the pixel!!! + writeData16(c); + + //TODO: Clean up this code!!! +} + +void ILI9341::writeCommand(char command) +{ + //Pull DC low for Command + m_DC = 0; + + //Pull CS low to select the TFT + m_CS = 0; + + //Write the command byte + m_SPI.write(command); + + //Pull CS high to end the transfer + m_CS = 1; +} + +void ILI9341::writeData8(char data) +{ + //Pull DC high for Data + m_DC = 1; + + //Pull CS low to select the TFT + m_CS = 0; + + //Write the data byte + m_SPI.write(data); + + //Pull CS high to end the transfer + m_CS = 1; +} + +void ILI9341::writeData16(unsigned short data) +{ + //Pull DC high for Data + m_DC = 1; + + //Pull CS low to select the TFT + m_CS = 0; + + //Write the 2 data bytes + m_SPI.write((char)(data >> 8)); + m_SPI.write((char)data); + + //Pull CS high to end the transfer + m_CS = 1; +}