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.

Drivers/ILI9341.cpp

Committer:
neilt6
Date:
2014-05-27
Revision:
3:a8f72d4864e6
Parent:
2:bbfc18022ee5

File content as of revision 3:a8f72d4864e6:

/* 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::flush()
{
    //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;
}