madhu sudhana
/
DL144128_LCD_b
output
Fork of display by
Diff: ili9163lcd.cpp
- Revision:
- 0:c0be4e018a09
- Child:
- 1:b64c81071d96
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ili9163lcd.cpp Sat Jun 14 02:27:06 2014 +0000 @@ -0,0 +1,442 @@ +/** + * @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 "mbed.h" +#include "font5x8.h" +#include "ili9163lcd.h" + +// Connection of mbed pins. +DigitalOut SCK_(D2); +DigitalOut SDA_(D3); +DigitalOut A0_(D4); +DigitalOut RESET_(D5); +DigitalOut CS_(D6); + +// Low-level LCD driving functions -------------------------------------------------------------------------- + +// Reset the LCD hardware +void lcdReset(void) +{ + // Reset pin is active low (0 = reset, 1 = ready) + RESET_ = 0; + wait_ms(50); + + RESET_ = 1; + wait_ms(120); +} + +void lcdWriteCommand(uint8_t address) +{ + uint8_t i; + + CS_ = 0; + A0_ = 0; + for(i=0;i<8;i++){ + if(address & 128)SDA_= 1; else SDA_ = 0; + SCK_ = 1; + address <<= 1; + SCK_ = 0; + } + wait_us(1); + CS_ = 1; +} + +void lcdWriteParameter(uint8_t parameter) +{ + uint8_t i; + + CS_ = 0; + A0_ = 1; + for(i=0;i<8;i++){ + if(parameter & 128)SDA_= 1; else SDA_ = 0; + SCK_ = 1; + parameter <<= 1; + SCK_ = 0; + } + wait_us(1); + CS_ = 1; +} + +void lcdWriteData(uint8_t dataByte1, uint8_t dataByte2) +{ + uint8_t i; + + CS_ = 0; + A0_ = 1; + for(i=0;i<8;i++){ + if(dataByte1 & 128)SDA_= 1; else SDA_ = 0; + SCK_ = 1; + dataByte1 <<= 1; + SCK_ = 0; + } + wait_us(1); + for(i=0;i<8;i++){ + if(dataByte2 & 128)SDA_= 1; else SDA_ = 0; + SCK_ = 1; + dataByte2 <<= 1; + SCK_ = 0; + } + wait_us(1); + CS_ = 1; +} + +// Initialise the display with the require screen orientation +void lcdInitialise(uint8_t orientation) +{ + CS_ = 1; + SCK_ = 0; + RESET_ = 1; + + // Hardware reset the LCD + lcdReset(); + + lcdWriteCommand(EXIT_SLEEP_MODE); + wait_ms(5); // Wait for the screen to wake up + + lcdWriteCommand(SET_PIXEL_FORMAT); + lcdWriteParameter(0x05); // 16 bits per pixel + + lcdWriteCommand(SET_GAMMA_CURVE); + lcdWriteParameter(0x04); // Select gamma curve 3 + + lcdWriteCommand(GAM_R_SEL); + lcdWriteParameter(0x01); // Gamma adjustment enabled + + lcdWriteCommand(POSITIVE_GAMMA_CORRECT); + lcdWriteParameter(0x3f); // 1st Parameter + lcdWriteParameter(0x25); // 2nd Parameter + lcdWriteParameter(0x1c); // 3rd Parameter + lcdWriteParameter(0x1e); // 4th Parameter + lcdWriteParameter(0x20); // 5th Parameter + lcdWriteParameter(0x12); // 6th Parameter + lcdWriteParameter(0x2a); // 7th Parameter + lcdWriteParameter(0x90); // 8th Parameter + lcdWriteParameter(0x24); // 9th Parameter + lcdWriteParameter(0x11); // 10th Parameter + lcdWriteParameter(0x00); // 11th Parameter + lcdWriteParameter(0x00); // 12th Parameter + lcdWriteParameter(0x00); // 13th Parameter + lcdWriteParameter(0x00); // 14th Parameter + lcdWriteParameter(0x00); // 15th Parameter + + lcdWriteCommand(NEGATIVE_GAMMA_CORRECT); + lcdWriteParameter(0x20); // 1st Parameter + lcdWriteParameter(0x20); // 2nd Parameter + lcdWriteParameter(0x20); // 3rd Parameter + lcdWriteParameter(0x20); // 4th Parameter + lcdWriteParameter(0x05); // 5th Parameter + lcdWriteParameter(0x00); // 6th Parameter + lcdWriteParameter(0x15); // 7th Parameter + lcdWriteParameter(0xa7); // 8th Parameter + lcdWriteParameter(0x3d); // 9th Parameter + lcdWriteParameter(0x18); // 10th Parameter + lcdWriteParameter(0x25); // 11th Parameter + lcdWriteParameter(0x2a); // 12th Parameter + lcdWriteParameter(0x2b); // 13th Parameter + lcdWriteParameter(0x2b); // 14th Parameter + lcdWriteParameter(0x3a); // 15th Parameter + + lcdWriteCommand(FRAME_RATE_CONTROL1); + lcdWriteParameter(0x08); // DIVA = 8 + lcdWriteParameter(0x08); // VPA = 8 + + lcdWriteCommand(DISPLAY_INVERSION); + lcdWriteParameter(0x07); // NLA = 1, NLB = 1, NLC = 1 (all on Frame Inversion) + + lcdWriteCommand(POWER_CONTROL1); + lcdWriteParameter(0x0a); // VRH = 10: GVDD = 4.30 + lcdWriteParameter(0x02); // VC = 2: VCI1 = 2.65 + + lcdWriteCommand(POWER_CONTROL2); + lcdWriteParameter(0x02); // BT = 2: AVDD = 2xVCI1, VCL = -1xVCI1, VGH = 5xVCI1, VGL = -2xVCI1 + + lcdWriteCommand(VCOM_CONTROL1); + lcdWriteParameter(0x50); // VMH = 80: VCOMH voltage = 4.5 + lcdWriteParameter(0x5b); // VML = 91: VCOML voltage = -0.225 + + lcdWriteCommand(VCOM_OFFSET_CONTROL); + lcdWriteParameter(0x40); // nVM = 0, VMF = 64: VCOMH output = VMH, VCOML output = VML + + lcdWriteCommand(SET_COLUMN_ADDRESS); + lcdWriteParameter(0x00); // XSH + lcdWriteParameter(0x00); // XSL + lcdWriteParameter(0x00); // XEH + lcdWriteParameter(0x7f); // XEL (128 pixels x) + + lcdWriteCommand(SET_PAGE_ADDRESS); + lcdWriteParameter(0x00); + lcdWriteParameter(0x00); + lcdWriteParameter(0x00); + lcdWriteParameter(0x7f); // 128 pixels y + + // Select display orientation + lcdWriteCommand(SET_ADDRESS_MODE); + lcdWriteParameter(orientation); + + // Set the display to on + lcdWriteCommand(SET_DISPLAY_ON); + lcdWriteCommand(WRITE_MEMORY_START); +} + +// LCD graphics functions ----------------------------------------------------------------------------------- + +void lcdClearDisplay(uint16_t colour) +{ + uint16_t pixel; + + // Set the column address to 0-127 + lcdWriteCommand(SET_COLUMN_ADDRESS); + lcdWriteParameter(0x00); + lcdWriteParameter(0x00); + lcdWriteParameter(0x00); + lcdWriteParameter(0x7f); + + // Set the page address to 0-127 + lcdWriteCommand(SET_PAGE_ADDRESS); + lcdWriteParameter(0x00); + lcdWriteParameter(0x00); + lcdWriteParameter(0x00); + lcdWriteParameter(0x7f); + + // Plot the pixels + lcdWriteCommand(WRITE_MEMORY_START); + for(pixel = 0; pixel < 16385; pixel++) lcdWriteData(colour >> 8, colour); +} + +void lcdPlot(uint8_t x, uint8_t y, uint16_t colour) +{ + // Horizontal Address Start Position + lcdWriteCommand(SET_COLUMN_ADDRESS); + lcdWriteParameter(0x00); + lcdWriteParameter(x); + lcdWriteParameter(0x00); + lcdWriteParameter(0x7f); + + // Vertical Address end Position + lcdWriteCommand(SET_PAGE_ADDRESS); + lcdWriteParameter(0x00); + lcdWriteParameter(y); + lcdWriteParameter(0x00); + lcdWriteParameter(0x7f); + + // Plot the point + lcdWriteCommand(WRITE_MEMORY_START); + lcdWriteData(colour >> 8, 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 lcdLine(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 + + lcdPlot(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 + lcdPlot(x0, y0, colour); + } + } + else + { + int fraction = dx - (dy >> 1); + while (y0 != y1) + { + if (fraction >= 0) + { + x0 += stepx; + fraction -= dy; + } + + y0 += stepy; + fraction += dx; + lcdPlot(x0, y0, colour); + } + } +} + +// Draw a rectangle between x0, y0 and x1, y1 +void lcdRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t colour) +{ + lcdLine(x0, y0, x0, y1, colour); + lcdLine(x0, y1, x1, y1, colour); + lcdLine(x1, y0, x1, y1, colour); + lcdLine(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 lcdFilledRectangle(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 + + lcdWriteCommand(SET_COLUMN_ADDRESS); // Horizontal Address Start Position + lcdWriteParameter(0x00); + lcdWriteParameter(x0); + lcdWriteParameter(0x00); + lcdWriteParameter(x1); + + lcdWriteCommand(SET_PAGE_ADDRESS); // Vertical Address end Position + lcdWriteParameter(0x00); + lcdWriteParameter(y0); + lcdWriteParameter(0x00); + lcdWriteParameter(0x7f); + + lcdWriteCommand(WRITE_MEMORY_START); + + for (pixels = 0; pixels < (((x1 - x0) + 1) * ((y1 - y0) + 1)); pixels++) + lcdWriteData(colour >> 8, 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 lcdCircle(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) + { + lcdPlot(xCentre + x, yCentre + y, colour); + lcdPlot(xCentre + y, yCentre + x, colour); + lcdPlot(xCentre - x, yCentre + y, colour); + lcdPlot(xCentre + y, yCentre - x, colour); + lcdPlot(xCentre - x, yCentre - y, colour); + lcdPlot(xCentre - y, yCentre - x, colour); + lcdPlot(xCentre + x, yCentre - y, colour); + lcdPlot(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 -------------------------------------------------------------------------- + +// Plot a character at the specified x, y co-ordinates (top left hand corner of character) +void lcdPutCh(unsigned char character, uint8_t x, uint8_t y, uint16_t fgColour, uint16_t bgColour) +{ + uint8_t row, column; + + // 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 + + lcdWriteCommand(SET_COLUMN_ADDRESS); // Horizontal Address Start Position + lcdWriteParameter(0x00); + lcdWriteParameter(x); + lcdWriteParameter(0x00); + lcdWriteParameter(x+5); + + lcdWriteCommand(SET_PAGE_ADDRESS); // Vertical Address end Position + lcdWriteParameter(0x00); + lcdWriteParameter(y); + lcdWriteParameter(0x00); + lcdWriteParameter(0x7f); + + lcdWriteCommand(WRITE_MEMORY_START); + + // Plot the font data + for (row = 0; row < 8; row++) + { + for (column = 0; column < 6; column++) + { + if ((font5x8[character][column]) & (1 << row)) + lcdWriteData(fgColour >> 8, fgColour); + else lcdWriteData(bgColour >> 8, bgColour); + } + } +} + +// Plot a string of characters to the LCD +void lcdPutS(const char *string, uint8_t x, uint8_t y, uint16_t fgColour, uint16_t bgColour) +{ + uint8_t origin = x; + + for (uint8_t characterNumber = 0; characterNumber < strlen(string); characterNumber++) + { + // Check if we are out of bounds and move to + // the next line if we are + if (x > 121) + { + x = origin; + y += 8; + } + + // If we move past the bottom of the screen just exit + if (y > 120) break; + + // Plot the current character + lcdPutCh(string[characterNumber], x, y, fgColour, bgColour); + x += 6; + } +}