Uses the same fonts as the SPI_TFT_ILI9341 Library (I have many, and a html/php font editor for that)
Embed:
(wiki syntax)
Show/hide line numbers
SPI_TFT_ILI9225.cpp
00001 /* 00002 Ported from arduino to mbed platform by Arman Safikhani 31-08-2015 00003 Jack: Many thanks Arman! 00004 00005 Changed a lot of things by Jack Berkhout 23-11-2016 00006 00007 Used for 2.2" Serial SPI TFT Color LCD Module for Arduino 00008 176*220 resolution / 11-pin / ILI9225 IC driver 00009 https://www.fasttech.com/product/3842400-2-2-serial-spi-tft-color-lcd-module-for-arduino 00010 00011 - Some code removed, some added, some changed 00012 - Now uses the same fonts as the SPI_TFT_ILI9341 Library (I have many, and a html/php font editor for that) 00013 - Text line interspacing can be set 00014 - The led backlight is using a PWM output, so it can be adjusted in brightness (from 0.0f = off to 1.0f = full brightness) 00015 - Added formatted printf 00016 - Added claim as standard output on stream 00017 - Orientation definitions are now related to the SD card slot location (front view) 00018 - Fast line functions hline and vline added, also used by outline reactangles, with drastical performance improvement (15 times) 00019 - Performance boost for filled shapes using new vline and hline functions 00020 - Get getStringWidth added 00021 */ 00022 00023 #include "SPI_TFT_ILI9225.h" 00024 00025 // Constructor when using software SPI. All output pins are configurable. 00026 TFT_22_ILI9225::TFT_22_ILI9225(PinName sdi, PinName clk, PinName cs, PinName rs, PinName rst, PinName led, const char *name) : 00027 _spi(sdi, NC, clk), _cs(cs), _rs(rs), _rst(rst), _led(led), Stream(name) 00028 { 00029 _spi.frequency(24000000); 00030 _spi.format(8, 0); 00031 00032 // PWM output to control backlight 00033 _led.period_ms(10); 00034 00035 // --- claim --- 00036 _row = 0; 00037 _column = 0; 00038 if (name == NULL) { 00039 _path = NULL; 00040 } else { 00041 _path = new char[strlen(name) + 2]; 00042 sprintf(_path, "/%s", name); 00043 } 00044 // --- /claim --- 00045 00046 init(); 00047 } 00048 00049 void TFT_22_ILI9225::init() 00050 { 00051 // Turn off backlight 00052 setBacklight(0.0f); 00053 00054 // Initialization Code 00055 _rst = 0;// Pull the reset pin low to reset ILI9225 00056 wait_ms(10); 00057 _rst = 1;// Pull the reset pin high to release the ILI9225C from the reset status 00058 wait_ms(50); 00059 00060 /* Start Initial Sequence */ 00061 /* Set SS bit and direction output from S528 to S1 */ 00062 _writeRegister(ILI9225_POWER_CTRL1, 0x0000); // Set SAP,DSTB,STB 00063 _writeRegister(ILI9225_POWER_CTRL2, 0x0000); // Set APON,PON,AON,VCI1EN,VC 00064 _writeRegister(ILI9225_POWER_CTRL3, 0x0000); // Set BT,DC1,DC2,DC3 00065 _writeRegister(ILI9225_POWER_CTRL4, 0x0000); // Set GVDD 00066 _writeRegister(ILI9225_POWER_CTRL5, 0x0000); // Set VCOMH/VCOML voltage 00067 wait_ms(40); 00068 00069 // Power-on sequence 00070 _writeRegister(ILI9225_POWER_CTRL2, 0x0018); // Set APON,PON,AON,VCI1EN,VC 00071 _writeRegister(ILI9225_POWER_CTRL3, 0x6121); // Set BT,DC1,DC2,DC3 00072 _writeRegister(ILI9225_POWER_CTRL4, 0x006F); // Set GVDD /*007F 0088 */ 00073 _writeRegister(ILI9225_POWER_CTRL5, 0x495F); // Set VCOMH/VCOML voltage 00074 _writeRegister(ILI9225_POWER_CTRL1, 0x0800); // Set SAP,DSTB,STB 00075 wait_ms(10); 00076 _writeRegister(ILI9225_POWER_CTRL2, 0x103B); // Set APON,PON,AON,VCI1EN,VC 00077 wait_ms(50); 00078 00079 _writeRegister(ILI9225_DRIVER_OUTPUT_CTRL, 0x011C); // set the display line number and display direction 00080 _writeRegister(ILI9225_LCD_AC_DRIVING_CTRL, 0x0100); // set 1 line inversion 00081 _writeRegister(ILI9225_ENTRY_MODE, 0x1030); // set GRAM write direction and BGR=1. 00082 _writeRegister(ILI9225_DISP_CTRL1, 0x0000); // Display off 00083 _writeRegister(ILI9225_BLANK_PERIOD_CTRL1, 0x0808); // set the back porch and front porch 00084 _writeRegister(ILI9225_FRAME_CYCLE_CTRL, 0x1100); // set the clocks number per line 00085 _writeRegister(ILI9225_INTERFACE_CTRL, 0x0000); // CPU interface 00086 _writeRegister(ILI9225_OSC_CTRL, 0x0D01); // Set Osc /*0e01*/ 00087 _writeRegister(ILI9225_VCI_RECYCLING, 0x0020); // Set VCI recycling 00088 _writeRegister(ILI9225_RAM_ADDR_SET1, 0x0000); // RAM Address 00089 _writeRegister(ILI9225_RAM_ADDR_SET2, 0x0000); // RAM Address 00090 00091 /* Set GRAM area */ 00092 _writeRegister(ILI9225_GATE_SCAN_CTRL, 0x0000); 00093 _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL1, 0x00DB); 00094 _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL2, 0x0000); 00095 _writeRegister(ILI9225_VERTICAL_SCROLL_CTRL3, 0x0000); 00096 _writeRegister(ILI9225_PARTIAL_DRIVING_POS1, 0x00DB); 00097 _writeRegister(ILI9225_PARTIAL_DRIVING_POS2, 0x0000); 00098 _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR1, 0x00AF); 00099 _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR2, 0x0000); 00100 _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR1, 0x00DB); 00101 _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR2, 0x0000); 00102 00103 /* Set GAMMA curve */ 00104 _writeRegister(ILI9225_GAMMA_CTRL1, 0x0000); 00105 _writeRegister(ILI9225_GAMMA_CTRL2, 0x0808); 00106 _writeRegister(ILI9225_GAMMA_CTRL3, 0x080A); 00107 _writeRegister(ILI9225_GAMMA_CTRL4, 0x000A); 00108 _writeRegister(ILI9225_GAMMA_CTRL5, 0x0A08); 00109 _writeRegister(ILI9225_GAMMA_CTRL6, 0x0808); 00110 _writeRegister(ILI9225_GAMMA_CTRL7, 0x0000); 00111 _writeRegister(ILI9225_GAMMA_CTRL8, 0x0A00); 00112 _writeRegister(ILI9225_GAMMA_CTRL9, 0x0710); 00113 _writeRegister(ILI9225_GAMMA_CTRL10, 0x0710); 00114 00115 _writeRegister(ILI9225_DISP_CTRL1, 0x0012); 00116 wait_ms(50); 00117 _writeRegister(ILI9225_DISP_CTRL1, 0x1017); 00118 00119 cls(); 00120 linespacing(0); 00121 setBacklight(1.0f); 00122 setOrientation(ILI9225_LANDSCAPE_B); 00123 foreground(COLOR_WHITE); 00124 background(COLOR_BLACK); 00125 } 00126 00127 void TFT_22_ILI9225::cls() 00128 { 00129 setBacklightOff(); 00130 _setWindowMax(); 00131 _rs = 1; 00132 _cs = 0; 00133 for (uint16_t i = width() * height(); i > 0; i--) { 00134 _spi.write(0x00); 00135 _spi.write(0x00); 00136 } 00137 _cs = 1; 00138 setBacklightOn(); 00139 gotoxy(0, 0); 00140 } 00141 00142 void TFT_22_ILI9225::fill(uint16_t color) 00143 { 00144 fillrect(0, 0, maxX(), maxY(), color); 00145 } 00146 00147 void TFT_22_ILI9225::invert(bool flag) 00148 { 00149 _writeCommand(0x00, flag ? ILI9225C_INVON : ILI9225C_INVOFF); 00150 } 00151 00152 void TFT_22_ILI9225::setBacklight(double brightness) 00153 { 00154 // PWM output to control backlight 00155 _brightness = brightness; 00156 _led.write(pow(brightness, 2)); // power(x, 2): For the eye better brightness response 00157 } 00158 00159 void TFT_22_ILI9225::setBacklightOff(void) 00160 { 00161 _led.write(0.0f); 00162 } 00163 00164 void TFT_22_ILI9225::setBacklightOn(void) 00165 { 00166 setBacklight(_brightness); 00167 } 00168 00169 void TFT_22_ILI9225::setDisplay(bool flag) 00170 { 00171 if (flag) { 00172 _writeRegister(0x00ff, 0x0000); 00173 _writeRegister(ILI9225_POWER_CTRL1, 0x0000); 00174 wait_ms(50); 00175 _writeRegister(ILI9225_DISP_CTRL1, 0x1017); 00176 wait_ms(200); 00177 } 00178 else { 00179 _writeRegister(0x00ff, 0x0000); 00180 _writeRegister(ILI9225_DISP_CTRL1, 0x0000); 00181 wait_ms(50); 00182 _writeRegister(ILI9225_POWER_CTRL1, 0x0003); 00183 wait_ms(200); 00184 } 00185 } 00186 00187 void TFT_22_ILI9225::setOrientation(uint8_t orientation) 00188 { 00189 _orientation = orientation % 4; 00190 // Entry Mode (R03h) 00191 // 0x1000 AM = 0: Horizontal, I/D[1:0] = 00: Horizontal: decrement, Vertical: decrement - ILI9225_PORTRAIT_R 00192 // 0x1010 AM = 0: Horizontal, I/D[1:0] = 01: Horizontal: increment, Vertical: decrement 00193 // 0x1020 AM = 0: Horizontal, I/D[1:0] = 10: Horizontal: decrement, Vertical: increment 00194 // 0x1030 AM = 0: Horizontal, I/D[1:0] = 11: Horizontal: increment, Vertical: increment - ILI9225_PORTRAIT_L 00195 // 0x1008 AM = 1: Vertical, I/D[1:0] = 00: Horizontal: decrement, Vertical: decrement 00196 // 0x1018 AM = 1: Vertical, I/D[1:0] = 01: Horizontal: increment, Vertical: decrement - ILI9225_LANDSCAPE_T 00197 // 0x1028 AM = 1: Vertical, I/D[1:0] = 10: Horizontal: decrement, Vertical: increment - ILI9225_LANDSCAPE_B 00198 // 0x1038 AM = 1: Vertical, I/D[1:0] = 11: Horizontal: increment, Vertical: increment 00199 00200 switch (_orientation) { 00201 case ILI9225_PORTRAIT_L: 00202 // 0x1030 AM = 0: Horizontal, I/D[1:0] = 11: Horizontal: increment, Vertical: increment 00203 _entryMode = 0x1030; 00204 _maxX = ILI9225_LCD_WIDTH; 00205 _maxY = ILI9225_LCD_HEIGHT; 00206 break; 00207 case ILI9225_LANDSCAPE_B: 00208 // 0x1028 AM = 1: Vertical, I/D[1:0] = 10: Horizontal: decrement, Vertical: increment 00209 _entryMode = 0x1028; 00210 _maxX = ILI9225_LCD_HEIGHT; 00211 _maxY = ILI9225_LCD_WIDTH; 00212 break; 00213 case ILI9225_PORTRAIT_R: 00214 // 0x1000 AM = 0: Horizontal, I/D[1:0] = 00: Horizontal: decrement, Vertical: decrement 00215 _entryMode = 0x1000; 00216 _maxX = ILI9225_LCD_WIDTH; 00217 _maxY = ILI9225_LCD_HEIGHT; 00218 break; 00219 case ILI9225_LANDSCAPE_T: 00220 // 0x1018 AM = 1: Vertical, I/D[1:0] = 01: Horizontal: increment, Vertical: decrement 00221 _entryMode = 0x1018; 00222 _maxX = ILI9225_LCD_HEIGHT; 00223 _maxY = ILI9225_LCD_WIDTH; 00224 break; 00225 } 00226 _writeRegister(ILI9225_ENTRY_MODE, _entryMode); // set GRAM write direction and BGR=1. 00227 } 00228 00229 uint8_t TFT_22_ILI9225::getOrientation() 00230 { 00231 return _orientation; 00232 } 00233 00234 00235 // Graphics functions 00236 00237 void TFT_22_ILI9225::pixel(uint16_t x1, uint16_t y1, uint16_t color) 00238 { 00239 if ((x1 >= _maxX) || (y1 >= _maxY)) return; 00240 00241 _setWindow(x1, y1, x1 + 1, y1 + 1); 00242 _orientCoordinates(x1, y1); 00243 _rs = 1; 00244 _cs = 0; 00245 _spi.write(color >> 8); 00246 _spi.write(color & 0xff); 00247 _cs = 1; 00248 } 00249 00250 void TFT_22_ILI9225::line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) 00251 { 00252 // Classic Bresenham algorithm 00253 int16_t steep = abs(y2 - y1) > abs(x2 - x1); 00254 int16_t dx, dy; 00255 00256 if (steep) { 00257 _swap(x1, y1); 00258 _swap(x2, y2); 00259 } 00260 00261 if (x1 > x2) { 00262 _swap(x1, x2); 00263 _swap(y1, y2); 00264 } 00265 00266 dx = x2 - x1; 00267 dy = abs(y2 - y1); 00268 00269 int16_t err = dx / 2; 00270 int16_t ystep; 00271 00272 if (y1 < y2) ystep = 1; 00273 else ystep = -1; 00274 00275 00276 for (; x1 <= x2; x1++) { 00277 if (steep) pixel(y1, x1, color); 00278 else pixel(x1, y1, color); 00279 00280 err -= dy; 00281 if (err < 0) { 00282 y1 += ystep; 00283 err += dx; 00284 } 00285 } 00286 } 00287 00288 void TFT_22_ILI9225::hline(uint16_t x1, uint16_t x2, uint16_t y, uint16_t color) 00289 { 00290 _writeRegister(ILI9225_ENTRY_MODE, 0x1028); // set GRAM write direction and BGR=1. 00291 _setWindow(x1, y, x2 + 1, y + 1); 00292 if (x2 < x1) { 00293 _swap(x1, x2); 00294 } 00295 _rs = 1; 00296 _cs = 0; 00297 for (uint16_t x = x1; x <= x2; x++) { 00298 _spi.write(color >> 8); 00299 _spi.write(color & 0xff); 00300 } 00301 _cs = 1; 00302 _writeRegister(ILI9225_ENTRY_MODE, _entryMode); // set GRAM write direction and BGR=1. 00303 } 00304 00305 void TFT_22_ILI9225::vline(uint16_t x, uint16_t y1, uint16_t y2, uint16_t color) 00306 { 00307 _writeRegister(ILI9225_ENTRY_MODE, 0x1010); // set GRAM write direction and BGR=1. 00308 _setWindow(x, y1, x + 1, y2 + 1); 00309 if (y2 < y1) { 00310 _swap(y1, y2); 00311 } 00312 _rs = 1; 00313 _cs = 0; 00314 for (uint16_t y = y1; y <= y2; y++) { 00315 _spi.write(color >> 8); 00316 _spi.write(color & 0xff); 00317 } 00318 _cs = 1; 00319 _writeRegister(ILI9225_ENTRY_MODE, _entryMode); // set GRAM write direction and BGR=1. 00320 } 00321 00322 void TFT_22_ILI9225::rect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { 00323 00324 vline(x1, y1, y2, color); 00325 hline(x1, x2, y1, color); 00326 hline(x1, x2, y2, color); 00327 vline(x2, y1, y2, color); 00328 } 00329 00330 void TFT_22_ILI9225::fillrect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) 00331 { 00332 _setWindow(x1, y1, x2, y2); 00333 _startData(); 00334 for (uint16_t t = (y2 - y1 + 1) * (x2 - x1 + 1); t > 0; t--) { 00335 _writeData(color); 00336 } 00337 _endData(); 00338 } 00339 00340 void TFT_22_ILI9225::circle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color) 00341 { 00342 int16_t f = 1 - r; 00343 int16_t ddF_x = 1; 00344 int16_t ddF_y = -2 * r; 00345 int16_t x = 0; 00346 int16_t y = r; 00347 00348 pixel(x0, y0 + r, color); 00349 pixel(x0, y0 - r, color); 00350 pixel(x0 + r, y0, color); 00351 pixel(x0 - r, y0, color); 00352 00353 while (x < y) { 00354 if (f >= 0) { 00355 y--; 00356 ddF_y += 2; 00357 f += ddF_y; 00358 } 00359 x++; 00360 ddF_x += 2; 00361 f += ddF_x; 00362 00363 pixel(x0 + x, y0 + y, color); 00364 pixel(x0 - x, y0 + y, color); 00365 pixel(x0 + x, y0 - y, color); 00366 pixel(x0 - x, y0 - y, color); 00367 pixel(x0 + y, y0 + x, color); 00368 pixel(x0 - y, y0 + x, color); 00369 pixel(x0 + y, y0 - x, color); 00370 pixel(x0 - y, y0 - x, color); 00371 } 00372 } 00373 00374 void TFT_22_ILI9225::fillcircle(uint8_t x0, uint8_t y0, uint8_t radius, uint16_t color) 00375 { 00376 int16_t f = 1 - radius; 00377 int16_t ddF_x = 1; 00378 int16_t ddF_y = -2 * radius; 00379 int16_t x = 0; 00380 int16_t y = radius; 00381 00382 while (x < y) { 00383 if (f >= 0) { 00384 y--; 00385 ddF_y += 2; 00386 f += ddF_y; 00387 } 00388 x++; 00389 ddF_x += 2; 00390 f += ddF_x; 00391 00392 hline(x0 + x, x0 - x, y0 + y, color); // bottom 00393 hline(x0 + x, x0 - x, y0 - y, color); // top 00394 vline(x0 + y, y0 - x, y0 + x, color); // right 00395 vline(x0 - y, y0 - x, y0 + x, color); // left 00396 } 00397 fillrect(x0 - x, y0 - y, x0 + x, y0 + y, color); 00398 } 00399 00400 void TFT_22_ILI9225::triangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color) 00401 { 00402 line(x1, y1, x2, y2, color); 00403 line(x2, y2, x3, y3, color); 00404 line(x3, y3, x1, y1, color); 00405 } 00406 00407 void TFT_22_ILI9225::filltriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color) 00408 { 00409 uint16_t a, b, y, last; 00410 00411 // Sort coordinates by Y order (y3 >= y2 >= y1) 00412 if (y1 > y2) { 00413 _swap(y1, y2); _swap(x1, x2); 00414 } 00415 if (y2 > y3) { 00416 _swap(y3, y2); _swap(x3, x2); 00417 } 00418 if (y1 > y2) { 00419 _swap(y1, y2); _swap(x1, x2); 00420 } 00421 00422 if (y1 == y3) { // Handle awkward all-on-same-line case as its own thing 00423 a = b = x1; 00424 if (x2 < a) a = x2; 00425 else if (x2 > b) b = x2; 00426 if (x3 < a) a = x3; 00427 else if (x3 > b) b = x3; 00428 hline(a, b, y1, color); 00429 return; 00430 } 00431 00432 uint16_t dx11 = x2 - x1, 00433 dy11 = y2 - y1, 00434 dx12 = x3 - x1, 00435 dy12 = y3 - y1, 00436 dx22 = x3 - x2, 00437 dy22 = y3 - y2, 00438 sa = 0, 00439 sb = 0; 00440 00441 // For upper part of triangle, find scanline crossings for segments 00442 // 0-1 and 0-2. If y2=y3 (flat-bottomed triangle), the scanline y2 00443 // is included here (and second loop will be skipped, avoiding a /0 00444 // error there), otherwise scanline y2 is skipped here and handled 00445 // in the second loop...which also avoids a /0 error here if y1=y2 00446 // (flat-topped triangle). 00447 if (y2 == y3) last = y2; // Include y2 scanline 00448 else last = y2 - 1; // Skip it 00449 00450 for (y = y1; y <= last; y++) { 00451 a = x1 + sa / dy11; 00452 b = x1 + sb / dy12; 00453 sa += dx11; 00454 sb += dx12; 00455 /* longhand: 00456 a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); 00457 b = x1 + (x3 - x1) * (y - y1) / (y3 - y1); 00458 */ 00459 if (a > b) _swap(a, b); 00460 hline(a, b, y, color); 00461 } 00462 00463 // For lower part of triangle, find scanline crossings for segments 00464 // 0-2 and 1-2. This loop is skipped if y2=y3. 00465 sa = dx22 * (y - y2); 00466 sb = dx12 * (y - y1); 00467 for (; y <= y3; y++) { 00468 a = x2 + sa / dy22; 00469 b = x1 + sb / dy12; 00470 sa += dx22; 00471 sb += dx12; 00472 /* longhand: 00473 a = x2 + (x3 - x2) * (y - y2) / (y3 - y2); 00474 b = x1 + (x3 - x1) * (y - y1) / (y3 - y1); 00475 */ 00476 if (a > b) _swap(a, b); 00477 hline(a, b, y, color); 00478 } 00479 } 00480 00481 void TFT_22_ILI9225::roundrect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t rad, bool fill, uint16_t color) 00482 { 00483 signed int a, b, P; 00484 00485 a = 0; // increment by 1 00486 b = rad; // decrement by 1 using P 00487 P = 1 - rad; 00488 00489 if (fill) 00490 { 00491 fillrect(x1, y1 + rad, x2, y2 - rad, color); 00492 00493 do 00494 { 00495 fillrect(x1 - a + rad, y1 - b + rad, a + x2 - rad, y1 - b + rad, color); // 8 --> 1 00496 fillrect(x1 - b + rad, y1 - a + rad, b + x2 - rad, y1 - a + rad, color); // 7 --> 2 00497 fillrect(x1 - b + rad, a + y2 - rad, b + x2 - rad, a + y2 - rad, color); // 6 --> 3 00498 fillrect(x1 - a + rad, b + y2 - rad, a + x2 - rad, b + y2 - rad, color); // 5 --> 4 00499 00500 if (P < 0) 00501 P += 3 + 2 * a++; 00502 else 00503 P += 5 + 2 * (a++ - b--); 00504 00505 } while (a <= b); 00506 } 00507 else 00508 { 00509 hline(x1 + rad, x2 - rad, y1, color); // top 00510 hline(x1 + rad, x2 - rad, y2, color); // bottom 00511 vline(x1, y1 + rad, y2 - rad, color); // left 00512 vline(x2, y1 + rad, y2 - rad, color); // right 00513 00514 do 00515 { 00516 pixel(a + x2 - rad, y1 - b + rad, color); // `````` Segment 1 00517 pixel(b + x2 - rad, y1 - a + rad, color); // `````` Segment 2 00518 00519 pixel(b + x2 - rad, a + y2 - rad, color); // `````` Segment 3 00520 pixel(a + x2 - rad, b + y2 - rad, color); // `````` Segment 4 00521 00522 pixel(x1 - a + rad, b + y2 - rad, color); // `````` Segment 5 00523 pixel(x1 - b + rad, a + y2 - rad, color); // `````` Segment 6 00524 00525 pixel(x1 - b + rad, y1 - a + rad, color); // `````` Segment 7 00526 pixel(x1 - a + rad, y1 - b + rad, color); // `````` Segment 8 00527 00528 if (P < 0) 00529 P += 3 + 2 * a++; 00530 else 00531 P += 5 + 2 * (a++ - b--); 00532 } while (a <= b); 00533 } 00534 } 00535 00536 uint16_t TFT_22_ILI9225::maxX(void) 00537 { 00538 return _maxX - 1; 00539 } 00540 00541 uint16_t TFT_22_ILI9225::maxY(void) 00542 { 00543 return _maxY - 1; 00544 } 00545 00546 uint16_t TFT_22_ILI9225::width(void) 00547 { 00548 return _maxX; 00549 } 00550 00551 uint16_t TFT_22_ILI9225::height(void) 00552 { 00553 return _maxY; 00554 } 00555 00556 uint16_t TFT_22_ILI9225::setColor(uint8_t red8, uint8_t green8, uint8_t blue8) 00557 { 00558 // rgb16 = red5 green6 blue5 00559 return (red8 >> 3) << 11 | (green8 >> 2) << 5 | (blue8 >> 3); 00560 } 00561 00562 void TFT_22_ILI9225::splitColor(uint16_t rgb, uint8_t &red, uint8_t &green, uint8_t &blue) 00563 { 00564 // rgb16 = red5 green6 blue5 00565 00566 red = (rgb & 0xF800) >> 11 << 3; 00567 green = (rgb & 0x7E0) >> 5 << 2; 00568 blue = (rgb & 0x1F) << 3; 00569 } 00570 00571 00572 // Text functions 00573 00574 void TFT_22_ILI9225::setFont(unsigned char* f) 00575 { 00576 font = f; 00577 } 00578 00579 uint8_t TFT_22_ILI9225::fontX(void) 00580 { 00581 return font[FONT_HORZ]; 00582 } 00583 00584 uint8_t TFT_22_ILI9225::fontY(void) 00585 { 00586 return font[FONT_VERT]; 00587 } 00588 00589 int TFT_22_ILI9225::putc(int value) 00590 { 00591 if (value == '\n') { // new line 00592 char_x = 0; 00593 char_y = char_y + (font[FONT_VERT] + char_line_spacing); 00594 if (char_y >= height() - (font[FONT_VERT] + char_line_spacing)) { 00595 char_y = 0; 00596 } 00597 return value; 00598 } 00599 if ((value < 32) || (value > 127)) { 00600 return value; 00601 } 00602 character(char_x, char_y, value); 00603 return value; 00604 } 00605 00606 void TFT_22_ILI9225::character(int x, int y, int c) 00607 { 00608 unsigned int hor, vert, offset, bpl, i, j, b; 00609 unsigned char* char_ptr; 00610 unsigned char z,w; 00611 00612 if ((c < 31) || (c > 127)) return; // test char range 00613 00614 // read font parameter from start of array 00615 offset = font[FONT_LENGTH]; // bytes / char 00616 hor = font[FONT_HORZ]; // get hor size of font 00617 vert = font[FONT_VERT]; // get vert size of font 00618 bpl = font[FONT_BYTES_VERT]; // bytes per line 00619 00620 if (char_x + hor > width()) { 00621 char_x = 0; 00622 char_y = char_y + vert + char_line_spacing; 00623 if (char_y >= height() - (vert + char_line_spacing)) { 00624 char_y = 0; 00625 } 00626 } 00627 _setWindow(char_x, char_y, (char_x+hor)-1, (char_y+vert)-1); 00628 00629 char_ptr = &font[((c -32) * offset) + 4]; // start of char bitmap 00630 w = char_ptr[0]; // width of actual char 00631 _startData(); 00632 00633 // Portrait 00634 for (j = 0; j < vert; j++) { // vert line 00635 for (i = 0; i < hor; i++) { // horz line 00636 z = char_ptr[bpl * i + ((j & 0xF8) >> 3)+1]; 00637 b = 1 << (j & 0x07); 00638 if (( z & b ) == 0x00) { 00639 _spi.write(_background >> 8); 00640 _spi.write(_background & 0xff); 00641 } else { 00642 _spi.write(_foreground >> 8); 00643 _spi.write(_foreground & 0xff); 00644 } 00645 } 00646 } 00647 00648 _endData(); 00649 _setWindowMax(); 00650 if ((w + 2) < hor) { // x offset to next char 00651 char_x += w + 2; 00652 } else { 00653 char_x += hor; 00654 } 00655 } 00656 00657 uint16_t TFT_22_ILI9225::getStringWidth(char * s) 00658 { 00659 unsigned char* char_ptr; 00660 uint16_t width = 0; 00661 uint16_t offset = font[FONT_LENGTH]; // bytes / char 00662 uint16_t hor = font[FONT_HORZ]; // get hor size of font 00663 00664 uint16_t len = strlen(s); 00665 for (uint8_t i = 0; i < len; i++) { 00666 if ((s[i] < 31) || (s[i] > 127)) { 00667 continue; // test char range 00668 } 00669 char_ptr = &font[((s[i] -32) * offset) + 4]; // start of char bitmap 00670 unsigned char w = char_ptr[0]; 00671 if ((w + 2) < hor) { // x offset to next char 00672 width += w + 2; 00673 } else { 00674 width += hor; 00675 } 00676 } 00677 return width - 1; 00678 } 00679 00680 void TFT_22_ILI9225::foreground(uint16_t color) 00681 { 00682 _foreground = color; 00683 } 00684 00685 void TFT_22_ILI9225::background(uint16_t color) 00686 { 00687 _background = color; 00688 } 00689 00690 void TFT_22_ILI9225::locate(int x, int y) 00691 { 00692 char_x = x; 00693 char_y = y; 00694 } 00695 00696 void TFT_22_ILI9225::gotoxy(int x, int y) 00697 { 00698 char_x = x * font[FONT_HORZ]; 00699 char_y = y * (font[FONT_VERT] + char_line_spacing); 00700 } 00701 00702 void TFT_22_ILI9225::home(void) 00703 { 00704 gotoxy(0, 0); 00705 } 00706 00707 void TFT_22_ILI9225::linespacing(int line_spacing) 00708 { 00709 char_line_spacing = line_spacing; 00710 } 00711 00712 int TFT_22_ILI9225::columns() 00713 { 00714 return width() / font[FONT_HORZ]; 00715 } 00716 00717 int TFT_22_ILI9225::rows() 00718 { 00719 return height() / font[FONT_VERT]; 00720 } 00721 00722 void TFT_22_ILI9225::unicode2ascii(char *uni_str, char *ascii_str) 00723 { 00724 int counter = 0; 00725 int Uch = 0; 00726 char chl, chh; 00727 00728 00729 while (*uni_str) 00730 { 00731 chl = *uni_str++; 00732 chh = *uni_str++; 00733 00734 Uch = 0; 00735 Uch = ((Uch | chh) << 8) | chl; 00736 00737 if (Uch > 1574 && Uch < 1591) 00738 *(ascii_str + counter) = (char)(Uch - 1376); 00739 else if (Uch > 1590 && Uch < 1595) 00740 *(ascii_str + counter) = (char)(Uch - 1375); 00741 else if (Uch > 1600 && Uch < 1603) 00742 *(ascii_str + counter) = (char)(Uch - 1380); 00743 else if (Uch == 1705) 00744 *(ascii_str + counter) = (char)(Uch - 1482); 00745 else if (Uch == 1604) 00746 *(ascii_str + counter) = (char)(Uch - 1379); 00747 else if (Uch > 1604 && Uch < 1609) 00748 *(ascii_str + counter) = (char)(Uch - 1378); 00749 else if (Uch == 1740) 00750 *(ascii_str + counter) = (char)(Uch - 1503); 00751 else if (Uch == 1574) 00752 *(ascii_str + counter) = (char)(Uch - 1381); 00753 else if (Uch == 1662) 00754 *(ascii_str + counter) = (char)(Uch - 1533); 00755 else if (Uch == 1670) 00756 *(ascii_str + counter) = (char)(Uch - 1529); 00757 else if (Uch == 1688) 00758 *(ascii_str + counter) = (char)(Uch - 1546); 00759 else if (Uch == 1711) 00760 *(ascii_str + counter) = (char)(Uch - 1567); 00761 else if (Uch == 1570) 00762 *(ascii_str + counter) = (char)(Uch - 1376); 00763 else if (Uch > 1631 && Uch < 1642) 00764 *(ascii_str + counter) = (char)(Uch - 1584); 00765 else if (Uch == 65536) 00766 *(ascii_str + counter) = NULL; 00767 else 00768 *(ascii_str + counter) = (char)Uch; 00769 00770 00771 counter++; 00772 00773 } 00774 *(ascii_str + counter) = NULL; 00775 } 00776 00777 bool TFT_22_ILI9225::claim (FILE *stream) 00778 { 00779 if ( _path == NULL) { 00780 fprintf(stderr, "claim requires a name to be given in the instantioator of the TextDisplay instance!\r\n"); 00781 return false; 00782 } 00783 if (freopen(_path, "w", stream) == NULL) { 00784 // Failed, should not happen 00785 return false; 00786 } 00787 // make sure we use line buffering 00788 setvbuf(stdout, NULL, _IOLBF, ILI9225_CHARS_PER_LINE); 00789 return true; 00790 } 00791 00792 // Private functions 00793 00794 void TFT_22_ILI9225::_swap(uint16_t &a, uint16_t &b) 00795 { 00796 uint16_t w = a; 00797 a = b; 00798 b = w; 00799 } 00800 00801 void TFT_22_ILI9225::_setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) 00802 { 00803 _orientCoordinates(x0, y0); 00804 _orientCoordinates(x1, y1); 00805 00806 if (x1 < x0) _swap(x0, x1); 00807 if (y1 < y0) _swap(y0, y1); 00808 00809 _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR1, x1); 00810 _writeRegister(ILI9225_HORIZONTAL_WINDOW_ADDR2, x0); 00811 00812 _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR1, y1); 00813 _writeRegister(ILI9225_VERTICAL_WINDOW_ADDR2, y0); 00814 00815 _writeRegister(ILI9225_RAM_ADDR_SET1, x0); 00816 _writeRegister(ILI9225_RAM_ADDR_SET2, y0); 00817 00818 _writeCommand(0x00, 0x22); 00819 } 00820 00821 void TFT_22_ILI9225::_setWindowMax(void) 00822 { 00823 _setWindow(0, 0, maxX(), maxY()); 00824 } 00825 00826 void TFT_22_ILI9225::_orientCoordinates(uint16_t &x, uint16_t &y) 00827 { 00828 switch (_orientation) { 00829 case 0: // ok 00830 break; 00831 case 1: // ok 00832 y = _maxY - y - 1; 00833 _swap(x, y); 00834 break; 00835 case 2: // ok 00836 x = _maxX - x - 1; 00837 y = _maxY - y - 1; 00838 break; 00839 case 3: // ok 00840 x = _maxX - x - 1; 00841 _swap(x, y); 00842 break; 00843 } 00844 } 00845 00846 void TFT_22_ILI9225::_writeRegister(uint16_t reg, uint16_t data) 00847 { 00848 _writeCommand(reg >> 8, reg & 0xff); 00849 _startData(); 00850 _writeData(data); 00851 _endData(); 00852 } 00853 00854 void TFT_22_ILI9225::_writeCommand(uint8_t HI, uint8_t LO) 00855 { 00856 _rs = 0; 00857 _cs = 0; 00858 _spi.write(HI); 00859 _spi.write(LO); 00860 _cs = 1; 00861 } 00862 00863 void TFT_22_ILI9225::_startData(void) 00864 { 00865 _rs = 1; 00866 _cs = 0; 00867 } 00868 00869 void TFT_22_ILI9225::_writeData(uint16_t data) 00870 { 00871 _spi.write(data >> 8); 00872 _spi.write(data & 0xff); 00873 } 00874 00875 void TFT_22_ILI9225::_endData(void) 00876 { 00877 _cs = 1; 00878 }
Generated on Sun Jul 17 2022 16:36:39 by 1.7.2