I simplified the library "ILI9225_TFT" provided by Arman Safikhani to better suit my needs in implementing a simple sliding puzzle game.

Revision:
3:251e4d020501
diff -r cc93245bb6d0 -r 251e4d020501 ILI9225.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ILI9225.cpp	Fri Apr 27 07:33:56 2018 +0000
@@ -0,0 +1,535 @@
+#include "ILI9225.h"
+#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
+
+int font_color, x_font, y_font;
+
+//Global Variables
+int x_text = 0, y_text = 0;
+int x_base = 0;
+
+//Constructor when using software SPI.  All output pins are configurable.
+ILI9225::ILI9225(PinName rst, PinName rs, PinName cs,
+    PinName sdi, PinName clk, PinName led) :
+    _rst(rst), _rs(rs), _cs(cs), _sdi(sdi), _clk(clk), spi(sdi, NC, clk),
+    _led(led), _rstInOut(_rst), _rsInOut(_rs), _csInOut(_cs), _ledInOut(_led),
+    hwSPI(true)
+{}
+
+void ILI9225::_orientCoordinates(uint16_t &x1, uint16_t &y1) {
+    switch (_orientation) {
+    case 0:
+        break;
+    case 1:
+        y1 = _maxY - y1 - 1;
+        _swap(x1, y1);
+        break;
+    case 2:
+        x1 = _maxX - x1 - 1;
+        y1 = _maxY - y1 - 1;
+        break;
+    case 3:
+        x1 = _maxX - x1 - 1;
+        _swap(x1, y1);
+        break;
+    }
+}
+
+void ILI9225::_setWindow(uint16_t x0, uint16_t y0, uint16_t x1,
+    uint16_t y1) {
+    _orientCoordinates(x0, y0);
+    _orientCoordinates(x1, y1);
+
+    if (x1 < x0)
+        _swap(x0, x1);
+    if (y1 < y0)
+        _swap(y0, y1);
+
+    _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR1, x1);
+    _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR2, x0);
+
+    _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR1, y1);
+    _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR2, y0);
+
+    _writeRegister(ILI9225_RAM_ADDR_SET1, x0);
+    _writeRegister(ILI9225_RAM_ADDR_SET2, y0);
+
+    _writeCommand(0x00, 0x22);
+}
+
+void ILI9225::begin() {
+    //Set up pins
+    _rsInOut.output();
+    _csInOut.output();
+    _rstInOut.output();
+
+    if (_led)
+        _ledInOut.output();
+    if (hwSPI) { //Using hardware SPI
+        spi.frequency(16000000);
+        spi.format(8, 0);
+    }
+    else {
+        DigitalInOut _clkInOut(_clk);
+        _clkInOut.output();
+        DigitalInOut _sdiInOut(_sdi);
+        _sdiInOut.output();
+    }
+
+    //Turn on backlight
+    if (_led)
+        _ledInOut = 1;
+
+    //Initialization Code
+    _rstInOut = 1; //Put reset pin high to release ILI9225C from reset status
+    wait_ms(1);
+    _rstInOut = 0; //Put reset pin low to reset ILI9225
+    wait_ms(10);
+    _rstInOut = 1; //Put reset pin high to release ILI9225C from reset status
+    wait_ms(50);
+
+    //Start Initial Sequence
+    //Set SS bit and direction output from S528 to S1
+    _writeRegister(ILI9225_POWER_CTRL1, 0x0000); //Set SAP,DSTB,STB
+    _writeRegister(ILI9225_POWER_CTRL2, 0x0000); //Set APON,PON,AON,VCI1EN,VC
+    _writeRegister(ILI9225_POWER_CTRL3, 0x0000); //Set BT,DC1,DC2,DC3
+    _writeRegister(ILI9225_POWER_CTRL4, 0x0000); //Set GVDD
+    _writeRegister(ILI9225_POWER_CTRL5, 0x0000); //Set VCOMH/VCOML voltage
+    wait_ms(40);
+
+    //Power-on sequence
+    _writeRegister(ILI9225_POWER_CTRL2, 0x0018); //Set APON,PON,AON,VCI1EN,VC
+    _writeRegister(ILI9225_POWER_CTRL3, 0x6121); //Set BT,DC1,DC2,DC3
+    _writeRegister(ILI9225_POWER_CTRL4, 0x006F); //Set GVDD   /*007F 0088 */
+    _writeRegister(ILI9225_POWER_CTRL5, 0x495F); //Set VCOMH/VCOML voltage
+    _writeRegister(ILI9225_POWER_CTRL1, 0x0800); //Set SAP,DSTB,STB
+    wait_ms(10);
+    _writeRegister(ILI9225_POWER_CTRL2, 0x103B); //Set APON,PON,AON,VCI1EN,VC
+    wait_ms(50);
+
+    //Set disp line # & disp dir
+    _writeRegister(ILI9225_DRIVER_OUTPUT_CTRL, 0x011C);
+    _writeRegister(ILI9225_LCD_AC_DRIVING_CTRL, 0x0100); //Set 1 line inversion
+    _writeRegister(ILI9225_ENTRY_MODE, 0x1030); //Set GRAM write dir & BGR=1.
+    _writeRegister(ILI9225_DISP_CTRL1, 0x0000); //Display off
+    _writeRegister(ILI9225_BLANK_PERIOD_CTRL1, 0x0808); //Set back & front porch
+    _writeRegister(ILI9225_FRAME_CYCLE_CTRL, 0x1100); //Set clocks # per line
+    _writeRegister(ILI9225_INTERFACE_CTRL, 0x0000); //CPU interface
+    _writeRegister(ILI9225_OSC_CTRL, 0x0D01); //Set Osc  /*0e01*/
+    _writeRegister(ILI9225_VCI_RECYCLING, 0x0020); //Set VCI recycling
+    _writeRegister(ILI9225_RAM_ADDR_SET1, 0x0000); //RAM Address
+    _writeRegister(ILI9225_RAM_ADDR_SET2, 0x0000); //RAM Address
+
+    //Set GRAM area
+    _writeRegister(ILI9225_GATE_SCAN_CTRL, 0x0000);
+    _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL1, 0x00DB);
+    _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL2, 0x0000);
+    _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL3, 0x0000);
+    _writeRegister(ILI9225_PARTIAL_DRIVING_POS1, 0x00DB);
+    _writeRegister(ILI9225_PARTIAL_DRIVING_POS2, 0x0000);
+    _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR1, 0x00AF);
+    _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR2, 0x0000);
+    _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR1, 0x00DB);
+    _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR2, 0x0000);
+
+    //Set GAMMA curve
+    _writeRegister(ILI9225_GAMMA_CTRL1, 0x0000);
+    _writeRegister(ILI9225_GAMMA_CTRL2, 0x0808);
+    _writeRegister(ILI9225_GAMMA_CTRL3, 0x080A);
+    _writeRegister(ILI9225_GAMMA_CTRL4, 0x000A);
+    _writeRegister(ILI9225_GAMMA_CTRL5, 0x0A08);
+    _writeRegister(ILI9225_GAMMA_CTRL6, 0x0808);
+    _writeRegister(ILI9225_GAMMA_CTRL7, 0x0000);
+    _writeRegister(ILI9225_GAMMA_CTRL8, 0x0A00);
+    _writeRegister(ILI9225_GAMMA_CTRL9, 0x0710);
+    _writeRegister(ILI9225_GAMMA_CTRL10, 0x0710);
+
+    _writeRegister(ILI9225_DISP_CTRL1, 0x0012);
+    wait_ms(50);
+    _writeRegister(ILI9225_DISP_CTRL1, 0x1017);
+
+    setBacklight(true);
+    setOrientation(0);
+
+    //Initialize variables
+    setBackgroundColor(COLOR_BLACK);
+
+    clear();
+}
+
+void ILI9225::clear() {
+    uint8_t old = _orientation;
+    setOrientation(0);
+    fillRectangle(0, 0, _maxX - 1, _maxY - 1, COLOR_BLACK);
+    setOrientation(old);
+    wait_ms(10);
+}
+
+void ILI9225::fill(uint16_t color) {
+    fillRectangle(0, 0, _maxX - 1, _maxY - 1, color);
+}
+
+void ILI9225::invert(bool flag) {
+    _writeCommand(0x00, flag ? ILI9225C_INVON : ILI9225C_INVOFF);
+}
+
+void ILI9225::setBacklight(bool flag) {
+    if (_led) _ledInOut = flag ? 1 : 0;
+}
+
+void ILI9225::setDisplay(bool flag) {
+    if (flag) {
+        _writeRegister(0x00ff, 0x0000);
+        _writeRegister(ILI9225_POWER_CTRL1, 0x0000);
+        wait_ms(50);
+        _writeRegister(ILI9225_DISP_CTRL1, 0x1017);
+        wait_ms(200);
+    }
+    else {
+        _writeRegister(0x00ff, 0x0000);
+        _writeRegister(ILI9225_DISP_CTRL1, 0x0000);
+        wait_ms(50);
+        _writeRegister(ILI9225_POWER_CTRL1, 0x0003);
+        wait_ms(200);
+    }
+}
+
+void ILI9225::setOrientation(uint8_t orientation) {
+    _orientation = orientation % 4;
+
+    switch (_orientation) {
+    case 0:
+        _maxX = ILI9225_LCD_WIDTH;
+        _maxY = ILI9225_LCD_HEIGHT;
+        break;
+    case 1:
+        _maxX = ILI9225_LCD_HEIGHT;
+        _maxY = ILI9225_LCD_WIDTH;
+        break;
+    case 2:
+        _maxX = ILI9225_LCD_WIDTH;
+        _maxY = ILI9225_LCD_HEIGHT;
+        break;
+    case 3:
+        _maxX = ILI9225_LCD_HEIGHT;
+        _maxY = ILI9225_LCD_WIDTH;
+        break;
+    }
+}
+
+void ILI9225::drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2,
+    uint16_t y2, uint16_t color) {
+    drawLine(x1, y1, x1, y2, color);
+    drawLine(x1, y1, x2, y1, color);
+    drawLine(x1, y2, x2, y2, color);
+    drawLine(x2, y1, x2, y2, color);
+}
+
+void ILI9225::fillRectangle(uint16_t x1, uint16_t y1, uint16_t x2,
+    uint16_t y2, uint16_t color) {
+    _setWindow(x1, y1, x2, y2);
+
+    for (uint16_t t = (y2 - y1 + 1) * (x2 - x1 + 1); t > 0; t--)
+        _writeData(color >> 8, color);
+}
+
+void ILI9225::drawLine(uint16_t x1, uint16_t y1, uint16_t x2,
+    uint16_t y2, uint16_t color) {
+    //Bresenham algorithm
+    int16_t steep = abs(y2 - y1) > abs(x2 - x1);
+    int16_t dx, dy;
+
+    if (steep) {
+        _swap(x1, y1);
+        _swap(x2, y2);
+    }
+
+    if (x1 > x2) {
+        _swap(x1, x2);
+        _swap(y1, y2);
+    }
+
+    dx = x2 - x1;
+    dy = abs(y2 - y1);
+
+    int16_t err = dx / 2;
+    int16_t ystep;
+
+    if (y1 < y2)
+        ystep = 1;
+    else   
+        ystep = -1;
+
+    for (; x1 <= x2; x1++) {
+        if(steep)
+            drawPixel(y1, x1, color);
+        else
+            drawPixel(x1, y1, color);
+
+        err -= dy;
+        if (err < 0) {
+            y1 += ystep;
+            err += dx;
+        }
+    }
+}
+
+void ILI9225::drawPixel(uint16_t x1, uint16_t y1, uint16_t color) {
+    if ((x1 >= _maxX) || (y1 >= _maxY))
+        return;
+
+    _setWindow(x1, y1, x1 + 1, y1 + 1);
+    _orientCoordinates(x1, y1);
+    _writeData(color >> 8, color);
+}
+
+uint16_t ILI9225::maxX() {
+    return _maxX;
+}
+
+uint16_t ILI9225::maxY() {
+    return _maxY;
+}
+
+uint16_t ILI9225::setColor(uint8_t red8, uint8_t green8, uint8_t blue8) {
+    //RGB16 = red5 green6 blue5
+    return (red8 >> 3) << 11 | (green8 >> 2) << 5 | (blue8 >> 3);
+}
+
+void ILI9225::splitColor(uint16_t rgb, uint8_t &red, uint8_t &green,
+    uint8_t &blue) {
+    //RGB16 = red5 green6 blue5
+    red = (rgb & 0xF800) >> 11 << 3;
+    green = (rgb & 0x7E0) >> 5 << 2;
+    blue = (rgb & 0x1F) << 3;
+}
+
+void ILI9225::_swap(uint16_t &a, uint16_t &b) {
+    uint16_t w = a;
+    a = b;
+    b = w;
+}
+
+//Utilities
+void ILI9225::_writeCommand(uint8_t HI, uint8_t LO) {
+    _rsInOut = 0;
+    _csInOut = 0;
+    spi.write(HI);
+    spi.write(LO);
+    _csInOut = 1;
+}
+
+void ILI9225::_writeData(uint8_t HI, uint8_t LO) {
+    _rsInOut = 1;
+    _csInOut = 0;
+    spi.write(HI);
+    spi.write(LO);
+    _csInOut = 1;
+}
+
+void ILI9225::_writeRegister(uint16_t reg, uint16_t data) {
+    _writeCommand(reg >> 8, reg & 255);
+    _writeData(data >> 8, data & 255);
+}
+
+void ILI9225::setBackgroundColor(uint16_t color) {
+    _bgColor = color;
+}
+
+void ILI9225::setFont(const uint8_t* font) {
+    cfont.font = font;
+    cfont.width = font[0];
+    cfont.height = font[1];
+    cfont.offset = font[2];
+    cfont.numchars = font[3];
+    cfont.nbrows = cfont.height / 8;
+
+    if (cfont.height % 8)
+        cfont.nbrows++; //Set # of bytes used by font height in multiples of 8.
+}
+
+void ILI9225::drawText(uint16_t x, uint16_t y, char *s, uint16_t color) {
+    uint16_t currx = x;
+
+    //Print every character in string
+    for (uint8_t k = 0; k < strlen(s); k++)
+        currx += drawChar(currx, y, s[k], color) + 1;
+}
+
+uint16_t ILI9225::drawChar(uint16_t x, uint16_t y, uint16_t ch,
+    uint16_t color) {
+    uint8_t charData, charWidth;
+    uint8_t h, i, j;
+    uint16_t charOffset;
+
+    //Bytes used by each character
+    charOffset = (cfont.width * cfont.nbrows) + 1;
+    //Char offset (add 4 for font header)
+    charOffset = (charOffset * (ch - cfont.offset)) + FONT_HEADER_SIZE;
+    //Get font width from 1st byte
+    charWidth = cfont.font[charOffset];
+    //Increment pointer to first character data byte
+    charOffset++;
+
+    //Loop through each font "column" (+1 blank column for spacing)
+    for (i = 0; i <= charWidth; i++) {
+        h = 0;  //Keep track of char height
+        for (j = 0; j < cfont.nbrows; j++) { //Each column byte
+            if (i == charWidth)
+                charData = (uint8_t)0x0; //Insert blank column
+            else
+                charData = cfont.font[charOffset];
+            charOffset++;
+
+            //Process every row in font character
+            for (uint8_t k = 0; k < 8; k++) {
+                if (h >= cfont.height)
+                    break;  //No need to process excess bits
+                if (bitRead(charData, k))
+                    drawPixel(x + i, y + (j * 8) + k, color);
+                else
+                    drawPixel(x + i, y + (j * 8) + k, _bgColor);
+                h++;
+            }
+        }
+    }
+    return charWidth;
+}
+
+//------------------------------------------------------------------------------
+//************************************* ECA 2.8 inch LCD Module ****************
+//------------------------------------------------------------------------------
+//Description  : Draws a beveled figure on the screen. 
+//Input        : x0, y0 - coordinate position of the upper left center
+//             : x1, y1 - coordinate position of the lower right center
+//             : rad    - defines the redius of the circle,
+//             : fill   - fill yes or no
+//------------------------------------------------------------------------------
+void ILI9225::roundRectangle(int x0, int y0, int x1, int y1, int rad,
+    bool fill, int color) {
+    signed int a, b, P;
+
+    a = 0; //Increment by 1
+    b = rad; //Decrement by 1 using P
+    P = 1 - rad;
+    if (fill) {
+        fillRectangle(x0, y0 + rad, x1, y1 - rad, color);
+
+        do {
+            fillRectangle(x0 - a + rad, y0 - b + rad, a + x1 - rad,
+                y0 - b + rad, color); //8 --> 1
+            fillRectangle(x0 - b + rad, y0 - a + rad, b + x1 - rad,
+                y0 - a + rad, color); //7 --> 2
+            fillRectangle(x0 - b + rad, a + y1 - rad, b + x1 - rad,
+                a + y1 - rad, color); //6 --> 3
+            fillRectangle(x0 - a + rad, b + y1 - rad, a + x1 - rad,
+                b + y1 - rad, color); //5 --> 4
+
+            if (P < 0)
+                P += 3 + 2 * a++;
+            else
+                P += 5 + 2 * (a++ - b--);
+
+        } while (a <= b);
+    } //Fill
+    else {
+        fillRectangle(x0 + rad, y0, x1 - rad, y0, color); //Top
+        fillRectangle(x0 + rad, y1, x1 - rad, y1, color); //Bottom
+        fillRectangle(x0, y0 + rad, x0, y1 - rad, color); //Left
+        fillRectangle(x1, y0 + rad, x1, y1 - rad, color); //Right
+
+        do {
+            drawPixel(a + x1 - rad, y0 - b + rad, color); // `````` Segment 1
+            drawPixel(b + x1 - rad, y0 - a + rad, color); // `````` Segment 2
+
+            drawPixel(b + x1 - rad, a + y1 - rad, color); // `````` Segment 3
+            drawPixel(a + x1 - rad, b + y1 - rad, color); // `````` Segment 4
+
+            drawPixel(x0 - a + rad, b + y1 - rad, color); // `````` Segment 5
+            drawPixel(x0 - b + rad, a + y1 - rad, color); // `````` Segment 6
+
+            drawPixel(x0 - b + rad, y0 - a + rad, color); // `````` Segment 7
+            drawPixel(x0 - a + rad, y0 - b + rad, color); // `````` Segment 8
+
+            if (P < 0)
+                P += 3 + 2 * a++;
+            else
+                P += 5 + 2 * (a++ - b--);
+        } while (a <= b);
+    } //No fill
+} //RoundRectangle
+
+//------------------------------------------------------------------------------
+//************************************* ECA 2.8 inch LCD Module ****************
+//------------------------------------------------------------------------------
+//Go to a specific pont for farsi font (x:0..TS_SIZE_X , y:0..TS_SIZE_Y)
+//------------------------------------------------------------------------------
+void ILI9225::goToXY(int x, int y) {
+    if ((x >= _maxX) || (x < 0)) {
+        x_font = 0;
+        x_base = 0;
+    }
+    else {
+        x_font = x;
+        x_base = x;
+    }
+    if ((y >= _maxY) || (y < 0))
+        y_font = 0;
+    else
+        y_font = y;
+}
+
+//------------------------------------------------------------------------------
+//************************************* ECA 2.8 inch LCD Module ****************
+//------------------------------------------------------------------------------
+//Make an ascii string from an unicode string 
+//------------------------------------------------------------------------------
+
+void ILI9225::unicode2ascii(char *uni_str, char *ascii_str) {
+    int counter = 0;
+    int Uch = 0;
+    char chl, chh;
+
+    while (*uni_str) {
+        chl = *uni_str++;
+        chh = *uni_str++;
+
+        Uch = 0;
+        Uch = ((Uch | chh) << 8) | chl;
+
+        if (Uch > 1574 && Uch < 1591)
+            *(ascii_str + counter) = (char)(Uch - 1376);
+        else if (Uch > 1590 && Uch < 1595)
+            *(ascii_str + counter) = (char)(Uch - 1375);
+        else if (Uch > 1600 && Uch < 1603)
+            *(ascii_str + counter) = (char)(Uch - 1380);
+        else if (Uch == 1705)
+            *(ascii_str + counter) = (char)(Uch - 1482);
+        else if (Uch == 1604)
+            *(ascii_str + counter) = (char)(Uch - 1379);
+        else if (Uch > 1604 && Uch < 1609)
+            *(ascii_str + counter) = (char)(Uch - 1378);
+        else if (Uch == 1740)
+            *(ascii_str + counter) = (char)(Uch - 1503);
+        else if (Uch == 1574)
+            *(ascii_str + counter) = (char)(Uch - 1381);
+        else if (Uch == 1662)
+            *(ascii_str + counter) = (char)(Uch - 1533);
+        else if (Uch == 1670)
+            *(ascii_str + counter) = (char)(Uch - 1529);
+        else if (Uch == 1688)
+            *(ascii_str + counter) = (char)(Uch - 1546);
+        else if (Uch == 1711)
+            *(ascii_str + counter) = (char)(Uch - 1567);
+        else if (Uch == 1570)
+            *(ascii_str + counter) = (char)(Uch - 1376);
+        else if (Uch > 1631 && Uch < 1642)
+            *(ascii_str + counter) = (char)(Uch - 1584);
+        else if (Uch == 65536)
+            *(ascii_str + counter) = NULL;
+        else
+            *(ascii_str + counter) = (char)Uch;
+
+        counter++;
+    }
+    *(ascii_str + counter) = NULL;
+}
\ No newline at end of file