Library for handling ILI9163 - based LCD displays.
Embed:
(wiki syntax)
Show/hide line numbers
ili9163lcd.cpp
00001 /** 00002 * @file ili9163lcd.c 00003 * @brief ILI9163 128x128 LCD Driver 00004 * 00005 * This code has been ported from the ili9163lcd library for mbed 00006 * made by Jun Morita. 00007 * Source form <http://files.noccylabs.info/lib430/liblcd/ili9163lcd_8c.html> 00008 * 00009 * This code has been ported from the ili9163lcd library for avr made 00010 * by Simon Inns, to run on a msp430. 00011 * 00012 * This program is free software: you can redistribute it and/or modify 00013 * it under the terms of the GNU General Public License as published by 00014 * the Free Software Foundation, either version 3 of the License, or 00015 * (at your option) any later version. 00016 * 00017 * This program is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU General Public License for more details. 00021 * 00022 * You should have received a copy of the GNU General Public License 00023 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00024 * 00025 * @author Jun Morita (iccraft) 00026 * @author Simon Inns <simon.inns@gmail.com> 00027 * @author Christopher Vagnetoft (NoccyLabs) 00028 * @copyright (C) 2012 Simon Inns 00029 * @copyright parts (C) 2012 NoccyLabs 00030 */ 00031 00032 #include "ili9163lcd.h" 00033 #include "mbed.h" 00034 00035 //-------------------------------------------------------------------------- 00036 // Initialize the object 00037 // 00038 ILI9163::ILI9163(PinName SCK, PinName SDA, PinName A0, PinName RESET, PinName CS, PinName LED) 00039 : SPI_(SDA, NC, SCK), A0_(A0), RESET_(RESET), CS_(CS), LED_(LED) 00040 { 00041 SPI_.format(8); 00042 //TODO: allow user to change interface frequency 00043 SPI_.frequency(20000000); 00044 00045 setFont((unsigned char*)font5x8); 00046 } 00047 00048 //-------------------------------------------------------------------------- 00049 // Low-level LCD driving functions 00050 00051 // Reset the LCD hardware 00052 void ILI9163::reset(void) 00053 { 00054 // Reset pin is active low (0 = reset, 1 = ready) 00055 RESET_ = 0; 00056 wait_ms(50); 00057 00058 RESET_ = 1; 00059 wait_ms(120); 00060 } 00061 00062 void ILI9163::writeCommand(uint8_t address) 00063 { 00064 CS_ = 0; 00065 A0_ = 0; 00066 SPI_.write(address); 00067 CS_ = 1; 00068 } 00069 00070 void ILI9163::writeParameter(uint8_t parameter) 00071 { 00072 CS_ = 0; 00073 A0_ = 1; 00074 SPI_.write(parameter); 00075 CS_ = 1; 00076 } 00077 00078 void ILI9163::writeData(uint16_t data) 00079 { 00080 CS_ = 0; 00081 A0_ = 1; 00082 SPI_.write(data >> 8); 00083 SPI_.write(data & 0xFF); 00084 CS_ = 1; 00085 } 00086 00087 // Initialize the display with the require screen orientation 00088 void ILI9163::init(uint8_t orientation) 00089 { 00090 CS_ = 1; 00091 RESET_ = 1; 00092 00093 // Hardware reset the LCD 00094 reset(); 00095 00096 writeCommand(EXIT_SLEEP_MODE); 00097 wait_ms(5); // Wait for the screen to wake up 00098 00099 writeCommand(SET_PIXEL_FORMAT); 00100 writeParameter(0x05); // 16 bits per pixel 00101 00102 writeCommand(SET_GAMMA_CURVE); 00103 writeParameter(0x04); // Select gamma curve 3 00104 00105 writeCommand(GAM_R_SEL); 00106 writeParameter(0x01); // Gamma adjustment enabled 00107 00108 writeCommand(POSITIVE_GAMMA_CORRECT); 00109 writeParameter(0x3f); // 1st Parameter 00110 writeParameter(0x25); // 2nd Parameter 00111 writeParameter(0x1c); // 3rd Parameter 00112 writeParameter(0x1e); // 4th Parameter 00113 writeParameter(0x20); // 5th Parameter 00114 writeParameter(0x12); // 6th Parameter 00115 writeParameter(0x2a); // 7th Parameter 00116 writeParameter(0x90); // 8th Parameter 00117 writeParameter(0x24); // 9th Parameter 00118 writeParameter(0x11); // 10th Parameter 00119 writeParameter(0x00); // 11th Parameter 00120 writeParameter(0x00); // 12th Parameter 00121 writeParameter(0x00); // 13th Parameter 00122 writeParameter(0x00); // 14th Parameter 00123 writeParameter(0x00); // 15th Parameter 00124 00125 writeCommand(NEGATIVE_GAMMA_CORRECT); 00126 writeParameter(0x20); // 1st Parameter 00127 writeParameter(0x20); // 2nd Parameter 00128 writeParameter(0x20); // 3rd Parameter 00129 writeParameter(0x20); // 4th Parameter 00130 writeParameter(0x05); // 5th Parameter 00131 writeParameter(0x00); // 6th Parameter 00132 writeParameter(0x15); // 7th Parameter 00133 writeParameter(0xa7); // 8th Parameter 00134 writeParameter(0x3d); // 9th Parameter 00135 writeParameter(0x18); // 10th Parameter 00136 writeParameter(0x25); // 11th Parameter 00137 writeParameter(0x2a); // 12th Parameter 00138 writeParameter(0x2b); // 13th Parameter 00139 writeParameter(0x2b); // 14th Parameter 00140 writeParameter(0x3a); // 15th Parameter 00141 00142 writeCommand(FRAME_RATE_CONTROL1); 00143 writeParameter(0x11); // DIVA = 17 00144 writeParameter(0x14); // VPA = 20 00145 00146 writeCommand(DISPLAY_INVERSION); 00147 writeParameter(0x07); // NLA = 1, NLB = 1, NLC = 1 (all on Frame Inversion) 00148 00149 writeCommand(POWER_CONTROL1); 00150 writeParameter(0x0a); // VRH = 10: GVDD = 4.30 00151 writeParameter(0x02); // VC = 2: VCI1 = 2.65 00152 00153 writeCommand(POWER_CONTROL2); 00154 writeParameter(0x02); // BT = 2: AVDD = 2xVCI1, VCL = -1xVCI1, VGH = 5xVCI1, VGL = -2xVCI1 00155 00156 writeCommand(VCOM_CONTROL1); 00157 writeParameter(0x50); // VMH = 80: VCOMH voltage = 4.5 00158 writeParameter(0x5b); // VML = 91: VCOML voltage = -0.225 00159 00160 writeCommand(VCOM_OFFSET_CONTROL); 00161 writeParameter(0x40); // nVM = 0, VMF = 64: VCOMH output = VMH, VCOML output = VML 00162 00163 writeCommand(SET_COLUMN_ADDRESS); 00164 writeParameter(0x00); // XSH 00165 writeParameter(0x00); // XSL 00166 writeParameter(0x00); // XEH 00167 writeParameter(0x7f); // XEL (128 pixels x) 00168 00169 writeCommand(SET_PAGE_ADDRESS); 00170 writeParameter(0x00); 00171 writeParameter(0x00); 00172 writeParameter(0x00); 00173 writeParameter(0x7f); // 128 pixels y 00174 00175 // Select display orientation 00176 writeCommand(SET_ADDRESS_MODE); 00177 writeParameter(orientation); 00178 00179 // Set the display to on 00180 writeCommand(SET_DISPLAY_ON); 00181 writeCommand(WRITE_MEMORY_START); 00182 } 00183 00184 // LCD graphics functions ----------------------------------------------------------------------------------- 00185 00186 void ILI9163::clearDisplay(uint16_t colour) 00187 { 00188 uint16_t pixel; 00189 00190 // Set the column address to 0-127 00191 writeCommand(SET_COLUMN_ADDRESS); 00192 writeParameter(0x00); 00193 writeParameter(0x00); 00194 writeParameter(0x00); 00195 writeParameter(0x7f); 00196 00197 // Set the page address to 0-127 00198 writeCommand(SET_PAGE_ADDRESS); 00199 writeParameter(0x00); 00200 writeParameter(0x00); 00201 writeParameter(0x00); 00202 writeParameter(0x7f); 00203 00204 // Plot the pixels 00205 writeCommand(WRITE_MEMORY_START); 00206 00207 for(pixel = 0; pixel < 128*128; pixel++) 00208 writeData(colour); 00209 } 00210 00211 void ILI9163::plot(uint8_t x, uint8_t y, uint16_t colour) 00212 { 00213 // Horizontal Address Start Position 00214 writeCommand(SET_COLUMN_ADDRESS); 00215 writeParameter(0x00); 00216 writeParameter(x); 00217 writeParameter(0x00); 00218 writeParameter(0x7f); 00219 00220 // Vertical Address end Position 00221 writeCommand(SET_PAGE_ADDRESS); 00222 writeParameter(0x00); 00223 writeParameter(y); 00224 writeParameter(0x00); 00225 writeParameter(0x7f); 00226 00227 // Plot the point 00228 writeCommand(WRITE_MEMORY_START); 00229 writeData(colour); 00230 } 00231 00232 // Draw a line from x0, y0 to x1, y1 00233 // Note: This is a version of Bresenham's line drawing algorithm 00234 // It only draws lines from left to right! 00235 void ILI9163::line(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t colour) 00236 { 00237 int16_t dy = y1 - y0; 00238 int16_t dx = x1 - x0; 00239 int16_t stepx, stepy; 00240 00241 if (dy < 0) 00242 { 00243 dy = -dy; stepy = -1; 00244 } 00245 else stepy = 1; 00246 00247 if (dx < 0) 00248 { 00249 dx = -dx; stepx = -1; 00250 } 00251 else stepx = 1; 00252 00253 dy <<= 1; // dy is now 2*dy 00254 dx <<= 1; // dx is now 2*dx 00255 00256 plot(x0, y0, colour); 00257 00258 if (dx > dy) { 00259 int fraction = dy - (dx >> 1); // same as 2*dy - dx 00260 while (x0 != x1) 00261 { 00262 if (fraction >= 0) 00263 { 00264 y0 += stepy; 00265 fraction -= dx; // same as fraction -= 2*dx 00266 } 00267 00268 x0 += stepx; 00269 fraction += dy; // same as fraction -= 2*dy 00270 plot(x0, y0, colour); 00271 } 00272 } 00273 else 00274 { 00275 int fraction = dx - (dy >> 1); 00276 while (y0 != y1) 00277 { 00278 if (fraction >= 0) 00279 { 00280 x0 += stepx; 00281 fraction -= dy; 00282 } 00283 00284 y0 += stepy; 00285 fraction += dx; 00286 plot(x0, y0, colour); 00287 } 00288 } 00289 } 00290 00291 // Draw a rectangle between x0, y0 and x1, y1 00292 void ILI9163::rectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t colour) 00293 { 00294 line(x0, y0, x0, y1, colour); 00295 line(x0, y1, x1, y1, colour); 00296 line(x1, y0, x1, y1, colour); 00297 line(x0, y0, x1, y0, colour); 00298 } 00299 00300 // Draw a filled rectangle 00301 // Note: y1 must be greater than y0 and x1 must be greater than x0 00302 // for this to work 00303 void ILI9163::filledRectangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t colour) 00304 { 00305 uint16_t pixels; 00306 00307 // To speed up plotting we define a x window with the width of the 00308 // rectangle and then just output the required number of bytes to 00309 // fill down to the end point 00310 00311 writeCommand(SET_COLUMN_ADDRESS); // Horizontal Address Start Position 00312 writeParameter(0x00); 00313 writeParameter(x0); 00314 writeParameter(0x00); 00315 writeParameter(x1); 00316 00317 writeCommand(SET_PAGE_ADDRESS); // Vertical Address end Position 00318 writeParameter(0x00); 00319 writeParameter(y0); 00320 writeParameter(0x00); 00321 writeParameter(0x7f); 00322 00323 writeCommand(WRITE_MEMORY_START); 00324 00325 for (pixels = 0; pixels < (((x1 - x0) + 1) * ((y1 - y0) + 1)); pixels++) 00326 writeData(colour);; 00327 } 00328 00329 // Draw a circle 00330 // Note: This is another version of Bresenham's line drawing algorithm. 00331 // There's plenty of documentation on the web if you are curious 00332 // how this works. 00333 void ILI9163::circle(int16_t xCentre, int16_t yCentre, int16_t radius, uint16_t colour) 00334 { 00335 int16_t x = 0, y = radius; 00336 int16_t d = 3 - (2 * radius); 00337 00338 while(x <= y) 00339 { 00340 plot(xCentre + x, yCentre + y, colour); 00341 plot(xCentre + y, yCentre + x, colour); 00342 plot(xCentre - x, yCentre + y, colour); 00343 plot(xCentre + y, yCentre - x, colour); 00344 plot(xCentre - x, yCentre - y, colour); 00345 plot(xCentre - y, yCentre - x, colour); 00346 plot(xCentre + x, yCentre - y, colour); 00347 plot(xCentre - y, yCentre + x, colour); 00348 00349 if (d < 0) d += (4 * x) + 6; 00350 else 00351 { 00352 d += (4 * (x - y)) + 10; 00353 y -= 1; 00354 } 00355 00356 x++; 00357 } 00358 } 00359 00360 // LCD text manipulation functions -------------------------------------------------------------------------- 00361 00362 // Change the font and store its size information 00363 void ILI9163::setFont(unsigned char* f) { 00364 font = f; 00365 font_bp_char = font[0]; // bytes per character 00366 font_hor = font[1]; // hor size of font 00367 font_vert = font[2]; // vert size of font 00368 font_bp_line = font[3]; // bytes per line 00369 } 00370 00371 // Plot a character at the specified x, y co-ordinates (top left hand corner of character) 00372 void ILI9163::putCh(unsigned char c, uint8_t x, uint8_t y, uint16_t fgColour, uint16_t bgColour) 00373 { 00374 uint16_t sign; 00375 unsigned char z; 00376 unsigned int j,i,b; 00377 00378 if ((c < 31) || (c > 127)) return; //Check if character is printable 00379 00380 // To speed up plotting we define a x window of 6 pixels and then 00381 // write out one row at a time. This means the LCD will correctly 00382 // update the memory pointer saving us a good few bytes 00383 00384 writeCommand(SET_COLUMN_ADDRESS); // Horizontal Address Start Position 00385 writeParameter(0x00); 00386 writeParameter(x); 00387 writeParameter(0x00); 00388 writeParameter(x+font_hor-1); // x + w -1 >> XEnd 00389 00390 writeCommand(SET_PAGE_ADDRESS); // Vertical Address end Position 00391 writeParameter(0x00); 00392 writeParameter(y); 00393 writeParameter(0x00); 00394 writeParameter(y+font_vert-1); // y + h -1 >> YEnd 0x7F 00395 00396 writeCommand(WRITE_MEMORY_START); 00397 00398 sign = (((c -32) * font_bp_char) + 4); // start of char bitmap 00399 00400 // Plot the font data 00401 for (j=0; j<font_vert; j++) { // vert line 00402 for (i=0; i<font_hor; i++) { // horz line 00403 z = font[sign + (font_bp_line * i) + ((j & 0xF8) >> 3)+1]; 00404 b = 1 << (j & 0x07); 00405 if (( z & b ) == 0x00) writeData(fgColour); 00406 else writeData(bgColour); 00407 } 00408 } 00409 } 00410 00411 // Plot a string of characters to the LCD 00412 void ILI9163::putS(const char *str, uint8_t x, uint8_t y, uint16_t fgColour, uint16_t bgColour) 00413 { 00414 uint8_t origin = x; 00415 00416 for (uint8_t i = 0; i < strlen(str); i++) 00417 { 00418 // Check if we are out of bounds and move to 00419 // the next line if we are 00420 if (x + font_hor > 127) 00421 { 00422 x = origin; 00423 y += font_vert; 00424 } 00425 00426 // If we move past the bottom of the screen just exit 00427 if (y + font_vert > 127) break; 00428 00429 // Plot the current character 00430 putCh(str[i], x, y, fgColour, bgColour); 00431 x += font_hor; 00432 } 00433 }
Generated on Fri Aug 12 2022 03:45:49 by 1.7.2