Library for handling ILI9163 - based LCD displays.
ILI9163 displays are typically 128*128 pixels with 15-bit color and controlled over 8-bit SPI.
This library is adapted from https://developer.mbed.org/teams/Temp/code/DL144128_LCD_b/, with some changes.
Revision 0:06faf770a0c7, committed 2017-01-25
- Comitter:
- jackmax
- Date:
- Wed Jan 25 23:46:47 2017 +0000
- Commit message:
- First commit
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/font5x8.h Wed Jan 25 23:46:47 2017 +0000 @@ -0,0 +1,114 @@ +/** + * @file font5x8.h + * @brief 5x8 Font Data + * + * This font was created by Philippe Lucidarme and is available + * from http://piclist.com/techref/datafile/charset/8x6.htm + */ + +#ifndef __ASSET_FONT_5X8 +#define __ASSET_FONT_5X8 +#define __FONT __ASSET_FONT + +// Note: This table is arranged according to ASCII codes 0 to 255 +const unsigned char font5x8[] = { +6,6,8,1, // Length,horz,vert,byte/vert +0x00,0x00,0x00,0x00,0x00,0x00, // 0x20 32 +0x00,0x00,0x00,0x6f,0x00,0x00, // ! 0x21 33 +0x00,0x00,0x07,0x00,0x07,0x00, // " 0x22 34 +0x00,0x14,0x7f,0x14,0x7f,0x14, // # 0x23 35 +0x00,0x00,0x07,0x04,0x1e,0x00, // $ 0x24 36 +0x00,0x23,0x13,0x08,0x64,0x62, // % 0x25 37 +0x00,0x36,0x49,0x56,0x20,0x50, // & 0x26 38 +0x00,0x00,0x00,0x07,0x00,0x00, // ' 0x27 39 +0x00,0x00,0x1c,0x22,0x41,0x00, // ( 0x28 40 +0x00,0x00,0x41,0x22,0x1c,0x00, // 0x29 41 +0x00,0x14,0x08,0x3e,0x08,0x14, // * 0x2a 42 +0x00,0x08,0x08,0x3e,0x08,0x08, // + 0x2b 43 +0x00,0x00,0x50,0x30,0x00,0x00, // , 0x2c 44 +0x00,0x08,0x08,0x08,0x08,0x08, // - 0x2d 45 +0x00,0x00,0x60,0x60,0x00,0x00, // . 0x2e 46 +0x00,0x20,0x10,0x08,0x04,0x02, // / 0x2f 47 +0x00,0x3e,0x51,0x49,0x45,0x3e, // 0 0x30 48 +0x00,0x00,0x42,0x7f,0x40,0x00, // 1 0x31 49 +0x00,0x42,0x61,0x51,0x49,0x46, // 2 0x32 50 +0x00,0x21,0x41,0x45,0x4b,0x31, // 3 0x33 51 +0x00,0x18,0x14,0x12,0x7f,0x10, // 4 0x34 52 +0x00,0x27,0x45,0x45,0x45,0x39, // 5 0x35 53 +0x00,0x3c,0x4a,0x49,0x49,0x30, // 6 0x36 54 +0x00,0x01,0x71,0x09,0x05,0x03, // 7 0x37 55 +0x00,0x36,0x49,0x49,0x49,0x36, // 8 0x38 56 +0x00,0x06,0x49,0x49,0x29,0x1e, // 9 0x39 57 +0x00,0x00,0x36,0x36,0x00,0x00, // : 0x3a 58 +0x00,0x00,0x56,0x36,0x00,0x00, // ; 0x3b 59 +0x00,0x08,0x14,0x22,0x41,0x00, // < 0x3c 60 +0x00,0x14,0x14,0x14,0x14,0x14, // = 0x3d 61 +0x00,0x00,0x41,0x22,0x14,0x08, // > 0x3e 62 +0x00,0x02,0x01,0x51,0x09,0x06, // ? 0x3f 63 +0x00,0x3e,0x41,0x5d,0x49,0x4e, // @ 0x40 64 +0x00,0x7e,0x09,0x09,0x09,0x7e, // A 0x41 65 +0x00,0x7f,0x49,0x49,0x49,0x36, // B 0x42 66 +0x00,0x3e,0x41,0x41,0x41,0x22, // C 0x43 67 +0x00,0x7f,0x41,0x41,0x41,0x3e, // D 0x44 68 +0x00,0x7f,0x49,0x49,0x49,0x41, // E 0x45 69 +0x00,0x7f,0x09,0x09,0x09,0x01, // F 0x46 70 +0x00,0x3e,0x41,0x49,0x49,0x7a, // G 0x47 71 +0x00,0x7f,0x08,0x08,0x08,0x7f, // H 0x48 72 +0x00,0x00,0x41,0x7f,0x41,0x00, // I 0x49 73 +0x00,0x20,0x40,0x41,0x3f,0x01, // J 0x4a 74 +0x00,0x7f,0x08,0x14,0x22,0x41, // K 0x4b 75 +0x00,0x7f,0x40,0x40,0x40,0x40, // L 0x4c 76 +0x00,0x7f,0x02,0x0c,0x02,0x7f, // M 0x4d 77 +0x00,0x7f,0x04,0x08,0x10,0x7f, // N 0x4e 78 +0x00,0x3e,0x41,0x41,0x41,0x3e, // O 0x4f 79 +0x00,0x7f,0x09,0x09,0x09,0x06, // P 0x50 80 +0x00,0x3e,0x41,0x51,0x21,0x5e, // Q 0x51 81 +0x00,0x7f,0x09,0x19,0x29,0x46, // R 0x52 82 +0x00,0x46,0x49,0x49,0x49,0x31, // S 0x53 83 +0x00,0x01,0x01,0x7f,0x01,0x01, // T 0x54 84 +0x00,0x3f,0x40,0x40,0x40,0x3f, // U 0x55 85 +0x00,0x0f,0x30,0x40,0x30,0x0f, // V 0x56 86 +0x00,0x3f,0x40,0x30,0x40,0x3f, // W 0x57 87 +0x00,0x63,0x14,0x08,0x14,0x63, // X 0x58 88 +0x00,0x07,0x08,0x70,0x08,0x07, // Y 0x59 89 +0x00,0x61,0x51,0x49,0x45,0x43, // Z 0x5a 90 +0x00,0x3c,0x4a,0x49,0x29,0x1e, // [ 0x5b 91 +0x00,0x02,0x04,0x08,0x10,0x20, // \ 0x5c 92 +0x00,0x00,0x41,0x7f,0x00,0x00, // ] 0x5d 93 +0x00,0x04,0x02,0x01,0x02,0x04, // ^ 0x5e 94 +0x00,0x40,0x40,0x40,0x40,0x40, // _ 0x5f 95 +0x00,0x00,0x00,0x03,0x04,0x00, // ` 0x60 96 +0x00,0x20,0x54,0x54,0x54,0x78, // a 0x61 97 +0x00,0x7f,0x48,0x44,0x44,0x38, // b 0x62 98 +0x00,0x38,0x44,0x44,0x44,0x20, // c 0x63 99 +0x00,0x38,0x44,0x44,0x48,0x7f, // d 0x64 100 +0x00,0x38,0x54,0x54,0x54,0x18, // e 0x65 101 +0x00,0x08,0x7e,0x09,0x01,0x02, // f 0x66 102 +0x00,0x0c,0x52,0x52,0x52,0x3e, // g 0x67 103 +0x00,0x7f,0x08,0x04,0x04,0x78, // h 0x68 104 +0x00,0x00,0x44,0x7d,0x40,0x00, // i 0x69 105 +0x00,0x20,0x40,0x44,0x3d,0x00, // j 0x6a 106 +0x00,0x00,0x7f,0x10,0x28,0x44, // k 0x6b 107 +0x00,0x00,0x41,0x7f,0x40,0x00, // l 0x6c 108 +0x00,0x7c,0x04,0x18,0x04,0x78, // m 0x6d 109 +0x00,0x7c,0x08,0x04,0x04,0x78, // n 0x6e 110 +0x00,0x38,0x44,0x44,0x44,0x38, // o 0x6f 111 +0x00,0x7c,0x14,0x14,0x14,0x08, // p 0x70 112 +0x00,0x08,0x14,0x14,0x18,0x7c, // q 0x71 113 +0x00,0x7c,0x08,0x04,0x04,0x08, // r 0x72 114 +0x00,0x48,0x54,0x54,0x54,0x20, // s 0x73 115 +0x00,0x04,0x3f,0x44,0x40,0x20, // t 0x74 116 +0x00,0x3c,0x40,0x40,0x20,0x7c, // u 0x75 117 +0x00,0x1c,0x20,0x40,0x20,0x1c, // v 0x76 118 +0x00,0x3c,0x40,0x30,0x40,0x3c, // w 0x77 119 +0x00,0x44,0x28,0x10,0x28,0x44, // x 0x78 120 +0x00,0x0c,0x50,0x50,0x50,0x3c, // y 0x79 121 +0x00,0x44,0x64,0x54,0x4c,0x44, // z 0x7a 122 +0x00,0x00,0x08,0x36,0x41,0x41, // { 0x7b 123 +0x00,0x00,0x00,0x7f,0x00,0x00, // | 0x7c 124 +0x00,0x41,0x41,0x36,0x08,0x00, // } 0x7d 125 +0x00,0x04,0x02,0x04,0x08,0x04, // ~ 0x7e 126 +0x00,0x7f,0x6b,0x6b,0x6b,0x7f, // 0x7f 127 +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ili9163lcd.cpp Wed Jan 25 23:46:47 2017 +0000 @@ -0,0 +1,433 @@ +/** + * @file ili9163lcd.c + * @brief ILI9163 128x128 LCD Driver + * + * This code has been ported from the ili9163lcd library for mbed + * made by Jun Morita. + * Source form <http://files.noccylabs.info/lib430/liblcd/ili9163lcd_8c.html> + * + * This code has been ported from the ili9163lcd library for avr made + * by Simon Inns, to run on a msp430. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @author Jun Morita (iccraft) + * @author Simon Inns <simon.inns@gmail.com> + * @author Christopher Vagnetoft (NoccyLabs) + * @copyright (C) 2012 Simon Inns + * @copyright parts (C) 2012 NoccyLabs + */ + +#include "ili9163lcd.h" +#include "mbed.h" + +//-------------------------------------------------------------------------- +// Initialize the object +// +ILI9163::ILI9163(PinName SCK, PinName SDA, PinName A0, PinName RESET, PinName CS, PinName LED) + : SPI_(SDA, NC, SCK), A0_(A0), RESET_(RESET), CS_(CS), LED_(LED) +{ + SPI_.format(8); + //TODO: allow user to change interface frequency + SPI_.frequency(20000000); + + setFont((unsigned char*)font5x8); +} + +//-------------------------------------------------------------------------- +// Low-level LCD driving functions + +// Reset the LCD hardware +void ILI9163::reset(void) +{ + // Reset pin is active low (0 = reset, 1 = ready) + RESET_ = 0; + wait_ms(50); + + RESET_ = 1; + wait_ms(120); +} + +void ILI9163::writeCommand(uint8_t address) +{ + CS_ = 0; + A0_ = 0; + SPI_.write(address); + CS_ = 1; +} + +void ILI9163::writeParameter(uint8_t parameter) +{ + CS_ = 0; + A0_ = 1; + SPI_.write(parameter); + CS_ = 1; +} + +void ILI9163::writeData(uint16_t data) +{ + CS_ = 0; + A0_ = 1; + SPI_.write(data >> 8); + SPI_.write(data & 0xFF); + CS_ = 1; +} + +// Initialize the display with the require screen orientation +void ILI9163::init(uint8_t orientation) +{ + CS_ = 1; + RESET_ = 1; + + // Hardware reset the LCD + reset(); + + writeCommand(EXIT_SLEEP_MODE); + wait_ms(5); // Wait for the screen to wake up + + writeCommand(SET_PIXEL_FORMAT); + writeParameter(0x05); // 16 bits per pixel + + writeCommand(SET_GAMMA_CURVE); + writeParameter(0x04); // Select gamma curve 3 + + writeCommand(GAM_R_SEL); + writeParameter(0x01); // Gamma adjustment enabled + + writeCommand(POSITIVE_GAMMA_CORRECT); + writeParameter(0x3f); // 1st Parameter + writeParameter(0x25); // 2nd Parameter + writeParameter(0x1c); // 3rd Parameter + writeParameter(0x1e); // 4th Parameter + writeParameter(0x20); // 5th Parameter + writeParameter(0x12); // 6th Parameter + writeParameter(0x2a); // 7th Parameter + writeParameter(0x90); // 8th Parameter + writeParameter(0x24); // 9th Parameter + writeParameter(0x11); // 10th Parameter + writeParameter(0x00); // 11th Parameter + writeParameter(0x00); // 12th Parameter + writeParameter(0x00); // 13th Parameter + writeParameter(0x00); // 14th Parameter + writeParameter(0x00); // 15th Parameter + + writeCommand(NEGATIVE_GAMMA_CORRECT); + writeParameter(0x20); // 1st Parameter + writeParameter(0x20); // 2nd Parameter + writeParameter(0x20); // 3rd Parameter + writeParameter(0x20); // 4th Parameter + writeParameter(0x05); // 5th Parameter + writeParameter(0x00); // 6th Parameter + writeParameter(0x15); // 7th Parameter + writeParameter(0xa7); // 8th Parameter + writeParameter(0x3d); // 9th Parameter + writeParameter(0x18); // 10th Parameter + writeParameter(0x25); // 11th Parameter + writeParameter(0x2a); // 12th Parameter + writeParameter(0x2b); // 13th Parameter + writeParameter(0x2b); // 14th Parameter + writeParameter(0x3a); // 15th Parameter + + writeCommand(FRAME_RATE_CONTROL1); + writeParameter(0x11); // DIVA = 17 + writeParameter(0x14); // VPA = 20 + + writeCommand(DISPLAY_INVERSION); + writeParameter(0x07); // NLA = 1, NLB = 1, NLC = 1 (all on Frame Inversion) + + writeCommand(POWER_CONTROL1); + writeParameter(0x0a); // VRH = 10: GVDD = 4.30 + writeParameter(0x02); // VC = 2: VCI1 = 2.65 + + writeCommand(POWER_CONTROL2); + writeParameter(0x02); // BT = 2: AVDD = 2xVCI1, VCL = -1xVCI1, VGH = 5xVCI1, VGL = -2xVCI1 + + writeCommand(VCOM_CONTROL1); + writeParameter(0x50); // VMH = 80: VCOMH voltage = 4.5 + writeParameter(0x5b); // VML = 91: VCOML voltage = -0.225 + + writeCommand(VCOM_OFFSET_CONTROL); + writeParameter(0x40); // nVM = 0, VMF = 64: VCOMH output = VMH, VCOML output = VML + + writeCommand(SET_COLUMN_ADDRESS); + writeParameter(0x00); // XSH + writeParameter(0x00); // XSL + writeParameter(0x00); // XEH + writeParameter(0x7f); // XEL (128 pixels x) + + writeCommand(SET_PAGE_ADDRESS); + writeParameter(0x00); + writeParameter(0x00); + writeParameter(0x00); + writeParameter(0x7f); // 128 pixels y + + // Select display orientation + writeCommand(SET_ADDRESS_MODE); + writeParameter(orientation); + + // Set the display to on + writeCommand(SET_DISPLAY_ON); + writeCommand(WRITE_MEMORY_START); +} + +// LCD graphics functions ----------------------------------------------------------------------------------- + +void ILI9163::clearDisplay(uint16_t colour) +{ + uint16_t pixel; + + // Set the column address to 0-127 + writeCommand(SET_COLUMN_ADDRESS); + writeParameter(0x00); + writeParameter(0x00); + writeParameter(0x00); + writeParameter(0x7f); + + // Set the page address to 0-127 + writeCommand(SET_PAGE_ADDRESS); + writeParameter(0x00); + writeParameter(0x00); + writeParameter(0x00); + writeParameter(0x7f); + + // Plot the pixels + writeCommand(WRITE_MEMORY_START); + + for(pixel = 0; pixel < 128*128; pixel++) + writeData(colour); +} + +void ILI9163::plot(uint8_t x, uint8_t y, uint16_t colour) +{ + // Horizontal Address Start Position + writeCommand(SET_COLUMN_ADDRESS); + writeParameter(0x00); + writeParameter(x); + writeParameter(0x00); + writeParameter(0x7f); + + // Vertical Address end Position + writeCommand(SET_PAGE_ADDRESS); + writeParameter(0x00); + writeParameter(y); + writeParameter(0x00); + writeParameter(0x7f); + + // Plot the point + writeCommand(WRITE_MEMORY_START); + writeData(colour); +} + +// Draw a line from x0, y0 to x1, y1 +// Note: This is a version of Bresenham's line drawing algorithm +// It only draws lines from left to right! +void ILI9163::line(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t colour) +{ + int16_t dy = y1 - y0; + int16_t dx = x1 - x0; + int16_t stepx, stepy; + + if (dy < 0) + { + dy = -dy; stepy = -1; + } + else stepy = 1; + + if (dx < 0) + { + dx = -dx; stepx = -1; + } + else stepx = 1; + + dy <<= 1; // dy is now 2*dy + dx <<= 1; // dx is now 2*dx + + plot(x0, y0, colour); + + if (dx > dy) { + int fraction = dy - (dx >> 1); // same as 2*dy - dx + while (x0 != x1) + { + if (fraction >= 0) + { + y0 += stepy; + fraction -= dx; // same as fraction -= 2*dx + } + + x0 += stepx; + fraction += dy; // same as fraction -= 2*dy + plot(x0, y0, colour); + } + } + else + { + int fraction = dx - (dy >> 1); + while (y0 != y1) + { + if (fraction >= 0) + { + x0 += stepx; + fraction -= dy; + } + + y0 += stepy; + fraction += dx; + plot(x0, y0, colour); + } + } +} + +// Draw a rectangle between x0, y0 and x1, y1 +void ILI9163::rectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t colour) +{ + line(x0, y0, x0, y1, colour); + line(x0, y1, x1, y1, colour); + line(x1, y0, x1, y1, colour); + line(x0, y0, x1, y0, colour); +} + +// Draw a filled rectangle +// Note: y1 must be greater than y0 and x1 must be greater than x0 +// for this to work +void ILI9163::filledRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t colour) +{ + uint16_t pixels; + + // To speed up plotting we define a x window with the width of the + // rectangle and then just output the required number of bytes to + // fill down to the end point + + writeCommand(SET_COLUMN_ADDRESS); // Horizontal Address Start Position + writeParameter(0x00); + writeParameter(x0); + writeParameter(0x00); + writeParameter(x1); + + writeCommand(SET_PAGE_ADDRESS); // Vertical Address end Position + writeParameter(0x00); + writeParameter(y0); + writeParameter(0x00); + writeParameter(0x7f); + + writeCommand(WRITE_MEMORY_START); + + for (pixels = 0; pixels < (((x1 - x0) + 1) * ((y1 - y0) + 1)); pixels++) + writeData(colour);; +} + +// Draw a circle +// Note: This is another version of Bresenham's line drawing algorithm. +// There's plenty of documentation on the web if you are curious +// how this works. +void ILI9163::circle(int16_t xCentre, int16_t yCentre, int16_t radius, uint16_t colour) +{ + int16_t x = 0, y = radius; + int16_t d = 3 - (2 * radius); + + while(x <= y) + { + plot(xCentre + x, yCentre + y, colour); + plot(xCentre + y, yCentre + x, colour); + plot(xCentre - x, yCentre + y, colour); + plot(xCentre + y, yCentre - x, colour); + plot(xCentre - x, yCentre - y, colour); + plot(xCentre - y, yCentre - x, colour); + plot(xCentre + x, yCentre - y, colour); + plot(xCentre - y, yCentre + x, colour); + + if (d < 0) d += (4 * x) + 6; + else + { + d += (4 * (x - y)) + 10; + y -= 1; + } + + x++; + } +} + +// LCD text manipulation functions -------------------------------------------------------------------------- + +// Change the font and store its size information +void ILI9163::setFont(unsigned char* f) { + font = f; + font_bp_char = font[0]; // bytes per character + font_hor = font[1]; // hor size of font + font_vert = font[2]; // vert size of font + font_bp_line = font[3]; // bytes per line +} + +// Plot a character at the specified x, y co-ordinates (top left hand corner of character) +void ILI9163::putCh(unsigned char c, uint8_t x, uint8_t y, uint16_t fgColour, uint16_t bgColour) +{ + uint16_t sign; + unsigned char z; + unsigned int j,i,b; + + if ((c < 31) || (c > 127)) return; //Check if character is printable + + // To speed up plotting we define a x window of 6 pixels and then + // write out one row at a time. This means the LCD will correctly + // update the memory pointer saving us a good few bytes + + writeCommand(SET_COLUMN_ADDRESS); // Horizontal Address Start Position + writeParameter(0x00); + writeParameter(x); + writeParameter(0x00); + writeParameter(x+font_hor-1); // x + w -1 >> XEnd + + writeCommand(SET_PAGE_ADDRESS); // Vertical Address end Position + writeParameter(0x00); + writeParameter(y); + writeParameter(0x00); + writeParameter(y+font_vert-1); // y + h -1 >> YEnd 0x7F + + writeCommand(WRITE_MEMORY_START); + + sign = (((c -32) * font_bp_char) + 4); // start of char bitmap + + // Plot the font data + for (j=0; j<font_vert; j++) { // vert line + for (i=0; i<font_hor; i++) { // horz line + z = font[sign + (font_bp_line * i) + ((j & 0xF8) >> 3)+1]; + b = 1 << (j & 0x07); + if (( z & b ) == 0x00) writeData(fgColour); + else writeData(bgColour); + } + } +} + +// Plot a string of characters to the LCD +void ILI9163::putS(const char *str, uint8_t x, uint8_t y, uint16_t fgColour, uint16_t bgColour) +{ + uint8_t origin = x; + + for (uint8_t i = 0; i < strlen(str); i++) + { + // Check if we are out of bounds and move to + // the next line if we are + if (x + font_hor > 127) + { + x = origin; + y += font_vert; + } + + // If we move past the bottom of the screen just exit + if (y + font_vert > 127) break; + + // Plot the current character + putCh(str[i], x, y, fgColour, bgColour); + x += font_hor; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ili9163lcd.h Wed Jan 25 23:46:47 2017 +0000 @@ -0,0 +1,209 @@ +/** + * @file ili9163lcd.h + * @brief ILI9163 128x128 LCD Driver (Header file) + * + * This code has been ported from the ili9163lcd library for mbed + * made by Jun Morita. + * Source form <http://files.noccylabs.info/lib430/liblcd/ili9163lcd_8c.html> + * + * This code has been ported from the ili9163lcd library for avr made + * by Simon Inns, to run on a msp430. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @author Jun Morita (iccraft) + * @author Simon Inns <simon.inns@gmail.com> + * @author Christopher Vagnetoft (NoccyLabs) + * @copyright (C) 2012 Simon Inns + * @copyright parts (C) 2012 NoccyLabs + */ + +#ifndef ILI9163LCD_H_ +#define ILI9163LCD_H_ + +#include "mbed.h" +#include "font5x8.h" + +// Screen orientation defines: +// 0 = Ribbon at top +// 1 = Ribbon at left +// 2 = Ribbon at right +// 3 = Ribbon at bottom +#define LCD_ORIENTATION0 0 +#define LCD_ORIENTATION1 96 +#define LCD_ORIENTATION2 160 +#define LCD_ORIENTATION3 192 + +// Each colour takes up 5 bits +// Green is shifted 6 bits to the left +// Blue is shifted 11 bits to the left +// some RGB color definitions BLUE GREEN RED +#define Black 0x0000 /* 0, 0, 0 */ +#define Maroon 0x000F /* 0, 0,15 */ +#define DarkGreen 0x03C0 /* 0,15, 0 */ +#define Navy 0x7800 /* 15, 0, 0 */ +#define Red 0x001F /* 0, 0,31 */ +#define Green 0x07C0 /* 0,31, 0 */ +#define Blue 0xF800 /* 31, 0, 0 */ +#define Yellow 0x07DF /* 0,31,31 */ +#define Magenta 0xF81F /* 31, 0,31 */ +#define Cyan 0xFFC0 /* 31,31, 0 */ +#define White 0xFFFF /* 31,31,31 */ + +class ILI9163 { + public: + // Definitions for control lines (port C) + static const uint8_t LCD_WR =(1 << 2); + static const uint8_t LCD_RS =(1 << 4); + static const uint8_t LCD_RD =(1 << 5); + static const uint8_t LCD_CS =(1 << 6); + static const uint8_t LCD_RESET =(1 << 7); + // ILI9163 LCD Controller Commands + static const uint8_t NOP = 0x00; + static const uint8_t SOFT_RESET = 0x01; + static const uint8_t GET_RED_CHANNEL = 0x06; + static const uint8_t GET_GREEN_CHANNEL = 0x07; + static const uint8_t GET_BLUE_CHANNEL = 0x08; + static const uint8_t GET_PIXEL_FORMAT = 0x0C; + static const uint8_t GET_POWER_MODE = 0x0A; + static const uint8_t GET_ADDRESS_MODE = 0x0B; + static const uint8_t GET_DISPLAY_MODE = 0x0D; + static const uint8_t GET_SIGNAL_MODE = 0x0E; + static const uint8_t GET_DIAGNOSTIC_RESULT = 0x0F; + static const uint8_t ENTER_SLEEP_MODE = 0x10; + static const uint8_t EXIT_SLEEP_MODE = 0x11; + static const uint8_t ENTER_PARTIAL_MODE = 0x12; + static const uint8_t ENTER_NORMAL_MODE = 0x13; + static const uint8_t EXIT_INVERT_MODE = 0x20; + static const uint8_t ENTER_INVERT_MODE = 0x21; + static const uint8_t SET_GAMMA_CURVE = 0x26; + static const uint8_t SET_DISPLAY_OFF = 0x28; + static const uint8_t SET_DISPLAY_ON = 0x29; + static const uint8_t SET_COLUMN_ADDRESS = 0x2A; + static const uint8_t SET_PAGE_ADDRESS = 0x2B; + static const uint8_t WRITE_MEMORY_START = 0x2C; + static const uint8_t WRITE_LUT = 0x2D; + static const uint8_t READ_MEMORY_START = 0x2E; + static const uint8_t SET_PARTIAL_AREA = 0x30; + static const uint8_t SET_SCROLL_AREA = 0x33; + static const uint8_t SET_TEAR_OFF = 0x34; + static const uint8_t SET_TEAR_ON = 0x35; + static const uint8_t SET_ADDRESS_MODE = 0x36; + static const uint8_t SET_SCROLL_START = 0x37; + static const uint8_t EXIT_IDLE_MODE = 0x38; + static const uint8_t ENTER_IDLE_MODE = 0x39; + static const uint8_t SET_PIXEL_FORMAT = 0x3A; + static const uint8_t WRITE_MEMORY_CONTINUE = 0x3C; + static const uint8_t READ_MEMORY_CONTINUE = 0x3E; + static const uint8_t SET_TEAR_SCANLINE = 0x44; + static const uint8_t GET_SCANLINE = 0x45; + static const uint8_t READ_ID1 = 0xDA; + static const uint8_t READ_ID2 = 0xDB; + static const uint8_t READ_ID3 = 0xDC; + static const uint8_t FRAME_RATE_CONTROL1 = 0xB1; + static const uint8_t FRAME_RATE_CONTROL2 = 0xB2; + static const uint8_t FRAME_RATE_CONTROL3 = 0xB3; + static const uint8_t DISPLAY_INVERSION = 0xB4; + static const uint8_t SOURCE_DRIVER_DIRECTION = 0xB7; + static const uint8_t GATE_DRIVER_DIRECTION = 0xB8; + static const uint8_t POWER_CONTROL1 = 0xC0; + static const uint8_t POWER_CONTROL2 = 0xC1; + static const uint8_t POWER_CONTROL3 = 0xC2; + static const uint8_t POWER_CONTROL4 = 0xC3; + static const uint8_t POWER_CONTROL5 = 0xC4; + static const uint8_t VCOM_CONTROL1 = 0xC5; + static const uint8_t VCOM_CONTROL2 = 0xC6; + static const uint8_t VCOM_OFFSET_CONTROL = 0xC7; + static const uint8_t WRITE_ID4_VALUE = 0xD3; + static const uint8_t NV_MEMORY_FUNCTION1 = 0xD7; + static const uint8_t NV_MEMORY_FUNCTION2 = 0xDE; + static const uint8_t POSITIVE_GAMMA_CORRECT = 0xE0; + static const uint8_t NEGATIVE_GAMMA_CORRECT = 0xE1; + static const uint8_t GAM_R_SEL = 0xF2; + + // Create the ILI9163 object + // + // @param D13 SCK + // @param D11 SDA + // @param D10 A0 + // @param D9 RESET pin connected to RESET of display + // @param D8 CS pin connected to CS of display + // @param D12 LED (optional) connected to LED pin (for controlling backlight) + // + // ILI9163 lcd(D13,D11,D10,D9,D8,D12); + // + ILI9163(PinName SCK, PinName SDA, PinName A0, PinName RESET, PinName CS, PinName LED = NC); + + SPI SPI_; + DigitalOut A0_; + DigitalOut RESET_; + DigitalOut CS_; + DigitalOut LED_; + + // font array + unsigned char* font; + uint8_t font_bp_char; // Bytes per character + uint8_t font_hor; // Horizontal size + uint8_t font_vert; // Vertical size + uint8_t font_bp_line; // Bytes per line + + // LCD function prototypes + void reset(void); + void writeCommand(uint8_t address); + void writeParameter(uint8_t parameter); + void writeData(uint16_t data); + void init(uint8_t orientation); + + //Theoretically, it is possible to use PWM to change the display brightness + //However, I found that it can interfere with data transfers, so I just use backlight on/off + inline void backlightOn() { LED_ = 1; }; + inline void backlightOff() { LED_ = 0; }; + inline void backlightToggle() { LED_ = !LED_; }; + + // Translates a 3 byte RGB value into a 2 byte value for the LCD (values should be 0-31) + static inline uint16_t colourFromRGB5(uint8_t r, uint8_t g, uint8_t b) + { return (b << 11) | (g << 6) | (r); } + + static inline uint16_t colourFromRGB8(uint8_t r, uint8_t g, uint8_t b) + { return colourFromRGB5(r >> 3, g >> 3, b >> 3); } + + void clearDisplay(uint16_t colour); + void plot(uint8_t x, uint8_t y, uint16_t colour); + void line(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t colour); + void rectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t colour); + void filledRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t colour); + void circle(int16_t xCentre, int16_t yCentre, int16_t radius, uint16_t colour); + + // select the font to use + // + // @param f pointer to font array + // + // font array can be created with GLCD Font Creator from http://www.mikroe.com + // you have to add 4 parameter at the beginning of the font array to use it: + // - the number of bytes per char + // - the vertical size in pixel + // - the horizontal size in pixel + // - the number of bytes per vertical line + // you also have to change the array to char[] + // + void setFont(unsigned char* f); + inline uint8_t lcdTextX(uint8_t x) { return x*font_hor; } + inline uint8_t lcdTextY(uint8_t y) { return y*font_vert; } + + void putCh(unsigned char character, uint8_t x, uint8_t y, uint16_t fgColour, uint16_t bgColour); + void putS(const char *string, uint8_t x, uint8_t y, uint16_t fgColour, uint16_t bgColour); + +}; // end class + +#endif /* ILI9163LCD_H_ */