PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1258 line
26KB

  1. /*
  2. UTFT.cpp - Arduino/chipKit library support for Color TFT LCD Boards
  3. Copyright (C)2010-2013 Henning Karlsen. All right reserved
  4. This library is the continuation of my ITDB02_Graph, ITDB02_Graph16
  5. and RGB_GLCD libraries for Arduino and chipKit. As the number of
  6. supported display modules and controllers started to increase I felt
  7. it was time to make a single, universal library as it will be much
  8. easier to maintain in the future.
  9. Basic functionality of this library was origianlly based on the
  10. demo-code provided by ITead studio (for the ITDB02 modules) and
  11. NKC Electronics (for the RGB GLCD module/shield).
  12. This library supports a number of 8bit, 16bit and serial graphic
  13. displays, and will work with both Arduino and chipKit boards. For a
  14. full list of tested display modules and controllers, see the
  15. document UTFT_Supported_display_modules_&_controllers.pdf.
  16. When using 8bit and 16bit display modules there are some
  17. requirements you must adhere to. These requirements can be found
  18. in the document UTFT_Requirements.pdf.
  19. There are no special requirements when using serial displays.
  20. You can always find the latest version of the library at
  21. http://electronics.henningkarlsen.com/
  22. If you make any modifications or improvements to the code, I would
  23. appreciate that you share the code with me so that I might include
  24. it in the next release. I can be contacted through
  25. http://electronics.henningkarlsen.com/contact.php.
  26. This library is free software; you can redistribute it and/or
  27. modify it under the terms of the CC BY-NC-SA 3.0 license.
  28. Please see the included documents for further information.
  29. */
  30. #include "UTFT.h"
  31. #include <pins_arduino.h>
  32. // Include hardware-specific functions for the correct MCU
  33. #if defined(__AVR__)
  34. #include <avr/pgmspace.h>
  35. #include "hardware/avr/HW_AVR.h"
  36. #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  37. #include "hardware/avr/HW_ATmega1280.h"
  38. #elif defined(__AVR_ATmega328P__)
  39. #include "hardware/avr/HW_ATmega328P.h"
  40. #elif defined(__AVR_ATmega32U4__)
  41. #include "hardware/avr/HW_ATmega32U4.h"
  42. #elif defined(__AVR_ATmega168__)
  43. #error "ATmega168 MCUs are not supported because they have too little flash memory!"
  44. #elif defined(__AVR_ATmega1284P__)
  45. #include "hardware/avr/HW_ATmega1284P.h"
  46. #else
  47. #error "Unsupported AVR MCU!"
  48. #endif
  49. #elif defined(__PIC32MX__)
  50. #include "hardware/pic32/HW_PIC32.h"
  51. #if defined(__32MX320F128H__)
  52. #pragma message("Compiling for chipKIT UNO32 (__32MX320F128H__)")
  53. #include "hardware/pic32/HW_PIC32MX320F128H.h"
  54. #elif defined(__32MX340F512H__)
  55. #pragma message("Compiling for chipKIT uC32 (__32MX340F512H__)")
  56. #include "hardware/pic32/HW_PIC32MX340F512H.h"
  57. #elif defined(__32MX795F512L__)
  58. #pragma message("Compiling for chipKIT MAX32 (__32MX795F512L__)")
  59. #include "hardware/pic32/HW_PIC32MX795F512L.h"
  60. #else
  61. #error "Unsupported PIC32 MCU!"
  62. #endif
  63. #elif defined(__arm__)
  64. #include "hardware/arm/HW_ARM.h"
  65. #if defined(__SAM3X8E__)
  66. #pragma message("Compiling for Arduino Due (AT91SAM3X8E)...")
  67. #include "hardware/arm/HW_SAM3X8E.h"
  68. #elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
  69. #pragma message("Compiling for Teensy 3.X...")
  70. #include "hardware/arm/HW_Teensy3.h"
  71. #else
  72. #error "Unsupported ARM MCU!"
  73. #endif
  74. #endif
  75. #include "memorysaver.h"
  76. UTFT::UTFT()
  77. {
  78. }
  79. UTFT::UTFT(byte model, int RS, int WR,int CS, int RST, int SER)
  80. {
  81. word dsx[] = {239, 239, 239, 239, 239, 239, 175, 175, 239, 127, 127, 239, 271, 479, 239, 239, 239, 239, 239, 239, 479, 319, 239, 175, 127, 239, 239, 319, 319};
  82. word dsy[] = {319, 399, 319, 319, 319, 319, 219, 219, 399, 159, 127, 319, 479, 799, 319, 319, 319, 319, 319, 319, 799, 479, 319, 219, 159, 319, 319, 479, 479};
  83. byte dtm[] = {16, 16, 16, 8, 8, 16, 8, SERIAL_4PIN, 16, SERIAL_5PIN, SERIAL_5PIN, 16, 16, 16, 8, 16, LATCHED_16, 8, 16, 8, 16, 16, 16, 8, SERIAL_5PIN, SERIAL_5PIN, SERIAL_4PIN, 16, 16};
  84. disp_x_size = dsx[model];
  85. disp_y_size = dsy[model];
  86. display_transfer_mode = dtm[model];
  87. display_model = model;
  88. if (display_transfer_mode == SERIAL_4PIN)
  89. {
  90. display_transfer_mode=1;
  91. display_serial_mode=SERIAL_4PIN;
  92. }
  93. if (display_transfer_mode == SERIAL_5PIN)
  94. {
  95. display_transfer_mode=1;
  96. display_serial_mode=SERIAL_5PIN;
  97. }
  98. if (display_transfer_mode!=1)
  99. {
  100. _set_direction_registers(display_transfer_mode);
  101. P_RS = portOutputRegister(digitalPinToPort(RS));
  102. B_RS = digitalPinToBitMask(RS);
  103. P_WR = portOutputRegister(digitalPinToPort(WR));
  104. B_WR = digitalPinToBitMask(WR);
  105. P_CS = portOutputRegister(digitalPinToPort(CS));
  106. B_CS = digitalPinToBitMask(CS);
  107. P_RST = portOutputRegister(digitalPinToPort(RST));
  108. B_RST = digitalPinToBitMask(RST);
  109. if (display_transfer_mode==LATCHED_16)
  110. {
  111. P_ALE = portOutputRegister(digitalPinToPort(SER));
  112. B_ALE = digitalPinToBitMask(SER);
  113. pinMode(SER,OUTPUT);
  114. cbi(P_ALE, B_ALE);
  115. pinMode(8,OUTPUT);
  116. digitalWrite(8, LOW);
  117. }
  118. pinMode(RS,OUTPUT);
  119. pinMode(WR,OUTPUT);
  120. pinMode(CS,OUTPUT);
  121. pinMode(RST,OUTPUT);
  122. }
  123. else
  124. {
  125. P_SDA = portOutputRegister(digitalPinToPort(RS));
  126. B_SDA = digitalPinToBitMask(RS);
  127. P_SCL = portOutputRegister(digitalPinToPort(WR));
  128. B_SCL = digitalPinToBitMask(WR);
  129. P_CS = portOutputRegister(digitalPinToPort(CS));
  130. B_CS = digitalPinToBitMask(CS);
  131. P_RST = portOutputRegister(digitalPinToPort(RST));
  132. B_RST = digitalPinToBitMask(RST);
  133. if (display_serial_mode!=SERIAL_4PIN)
  134. {
  135. P_RS = portOutputRegister(digitalPinToPort(SER));
  136. B_RS = digitalPinToBitMask(SER);
  137. pinMode(SER,OUTPUT);
  138. }
  139. pinMode(RS,OUTPUT);
  140. pinMode(WR,OUTPUT);
  141. pinMode(CS,OUTPUT);
  142. pinMode(RST,OUTPUT);
  143. }
  144. }
  145. void UTFT::LCD_Write_COM(char VL)
  146. {
  147. if (display_transfer_mode!=1)
  148. {
  149. cbi(P_RS, B_RS);
  150. LCD_Writ_Bus(0x00,VL,display_transfer_mode);
  151. }
  152. else
  153. LCD_Writ_Bus(0x00,VL,display_transfer_mode);
  154. }
  155. void UTFT::LCD_Write_DATA(char VH,char VL)
  156. {
  157. if (display_transfer_mode!=1)
  158. {
  159. sbi(P_RS, B_RS);
  160. LCD_Writ_Bus(VH,VL,display_transfer_mode);
  161. }
  162. else
  163. {
  164. LCD_Writ_Bus(0x01,VH,display_transfer_mode);
  165. LCD_Writ_Bus(0x01,VL,display_transfer_mode);
  166. }
  167. }
  168. void UTFT::LCD_Write_DATA(char VL)
  169. {
  170. if (display_transfer_mode!=1)
  171. {
  172. sbi(P_RS, B_RS);
  173. LCD_Writ_Bus(0x00,VL,display_transfer_mode);
  174. }
  175. else
  176. LCD_Writ_Bus(0x01,VL,display_transfer_mode);
  177. }
  178. void UTFT::LCD_Write_COM_DATA(char com1,int dat1)
  179. {
  180. LCD_Write_COM(com1);
  181. LCD_Write_DATA(dat1>>8,dat1);
  182. }
  183. void UTFT::InitLCD(byte orientation)
  184. {
  185. orient=orientation;
  186. _hw_special_init();
  187. sbi(P_RST, B_RST);
  188. delay(5);
  189. cbi(P_RST, B_RST);
  190. delay(15);
  191. sbi(P_RST, B_RST);
  192. delay(15);
  193. cbi(P_CS, B_CS);
  194. switch(display_model)
  195. {
  196. #ifndef DISABLE_HX8347A
  197. #include "tft_drivers/hx8347a/initlcd.h"
  198. #endif
  199. #ifndef DISABLE_ILI9327
  200. #include "tft_drivers/ili9327/initlcd.h"
  201. #endif
  202. #ifndef DISABLE_SSD1289
  203. #include "tft_drivers/ssd1289/initlcd.h"
  204. #endif
  205. #ifndef DISABLE_ILI9325C
  206. #include "tft_drivers/ili9325c/initlcd.h"
  207. #endif
  208. #ifndef DISABLE_ILI9325D
  209. #include "tft_drivers/ili9325d/default/initlcd.h"
  210. #endif
  211. #ifndef DISABLE_ILI9325D_ALT
  212. #include "tft_drivers/ili9325d/alt/initlcd.h"
  213. #endif
  214. #ifndef DISABLE_HX8340B_8
  215. #include "tft_drivers/hx8340b/8/initlcd.h"
  216. #endif
  217. #ifndef DISABLE_HX8340B_S
  218. #include "tft_drivers/hx8340b/s/initlcd.h"
  219. #endif
  220. #ifndef DISABLE_ST7735
  221. #include "tft_drivers/st7735/initlcd.h"
  222. #endif
  223. #ifndef DISABLE_PCF8833
  224. #include "tft_drivers/pcf8833/initlcd.h"
  225. #endif
  226. #ifndef DISABLE_S1D19122
  227. #include "tft_drivers/s1d19122/initlcd.h"
  228. #endif
  229. #ifndef DISABLE_HX8352A
  230. #include "tft_drivers/hx8352a/initlcd.h"
  231. #endif
  232. #ifndef DISABLE_SSD1963_480
  233. #include "tft_drivers/ssd1963/480/initlcd.h"
  234. #endif
  235. #ifndef DISABLE_SSD1963_800
  236. #include "tft_drivers/ssd1963/800/initlcd.h"
  237. #endif
  238. #ifndef DISABLE_SSD1963_800_ALT
  239. #include "tft_drivers/ssd1963/800alt/initlcd.h"
  240. #endif
  241. #ifndef DISABLE_S6D1121
  242. #include "tft_drivers/s6d1121/initlcd.h"
  243. #endif
  244. #ifndef DISABLE_ILI9320
  245. #include "tft_drivers/ili9320/initlcd.h"
  246. #endif
  247. #ifndef DISABLE_ILI9481
  248. #include "tft_drivers/ili9481/initlcd.h"
  249. #endif
  250. #ifndef DISABLE_S6D0164
  251. #include "tft_drivers/s6d0164/initlcd.h"
  252. #endif
  253. #ifndef DISABLE_ST7735S
  254. #include "tft_drivers/st7735s/initlcd.h"
  255. #endif
  256. #ifndef DISABLE_ILI9341_S4P
  257. #include "tft_drivers/ili9341/s4p/initlcd.h"
  258. #endif
  259. #ifndef DISABLE_ILI9341_S5P
  260. #include "tft_drivers/ili9341/s5p/initlcd.h"
  261. #endif
  262. #ifndef DISABLE_R61581
  263. #include "tft_drivers/r61581/initlcd.h"
  264. #endif
  265. #ifndef DISABLE_ILI9486
  266. #include "tft_drivers/ili9486/initlcd.h"
  267. #endif
  268. }
  269. sbi (P_CS, B_CS);
  270. setColor(255, 255, 255);
  271. setBackColor(0, 0, 0);
  272. cfont.font=0;
  273. _transparent = false;
  274. }
  275. void UTFT::setXY(word x1, word y1, word x2, word y2)
  276. {
  277. if (orient==LANDSCAPE)
  278. {
  279. swap(word, x1, y1);
  280. swap(word, x2, y2)
  281. y1=disp_y_size-y1;
  282. y2=disp_y_size-y2;
  283. swap(word, y1, y2)
  284. }
  285. switch(display_model)
  286. {
  287. #ifndef DISABLE_HX8347A
  288. #include "tft_drivers/hx8347a/setxy.h"
  289. #endif
  290. #ifndef DISABLE_HX8352A
  291. #include "tft_drivers/hx8352a/setxy.h"
  292. #endif
  293. #ifndef DISABLE_ILI9327
  294. #include "tft_drivers/ili9327/setxy.h"
  295. #endif
  296. #ifndef DISABLE_SSD1289
  297. #include "tft_drivers/ssd1289/setxy.h"
  298. #endif
  299. #ifndef DISABLE_ILI9325C
  300. #include "tft_drivers/ili9325c/setxy.h"
  301. #endif
  302. #ifndef DISABLE_ILI9325D
  303. #include "tft_drivers/ili9325d/default/setxy.h"
  304. #endif
  305. #ifndef DISABLE_ILI9325D_ALT
  306. #include "tft_drivers/ili9325d/alt/setxy.h"
  307. #endif
  308. #ifndef DISABLE_HX8340B_8
  309. #include "tft_drivers/hx8340b/8/setxy.h"
  310. #endif
  311. #ifndef DISABLE_HX8340B_S
  312. #include "tft_drivers/hx8340b/s/setxy.h"
  313. #endif
  314. #ifndef DISABLE_ST7735
  315. #include "tft_drivers/st7735/setxy.h"
  316. #endif
  317. #ifndef DISABLE_S1D19122
  318. #include "tft_drivers/s1d19122/setxy.h"
  319. #endif
  320. #ifndef DISABLE_PCF8833
  321. #include "tft_drivers/pcf8833/setxy.h"
  322. #endif
  323. #ifndef DISABLE_SSD1963_480
  324. #include "tft_drivers/ssd1963/480/setxy.h"
  325. #endif
  326. #ifndef DISABLE_SSD1963_800
  327. #include "tft_drivers/ssd1963/800/setxy.h"
  328. #endif
  329. #ifndef DISABLE_SSD1963_800_ALT
  330. #include "tft_drivers/ssd1963/800alt/setxy.h"
  331. #endif
  332. #ifndef DISABLE_S6D1121
  333. #include "tft_drivers/s6d1121/setxy.h"
  334. #endif
  335. #ifndef DISABLE_ILI9320
  336. #include "tft_drivers/ili9320/setxy.h"
  337. #endif
  338. #ifndef DISABLE_ILI9481
  339. #include "tft_drivers/ili9481/setxy.h"
  340. #endif
  341. #ifndef DISABLE_S6D0164
  342. #include "tft_drivers/s6d0164/setxy.h"
  343. #endif
  344. #ifndef DISABLE_ST7735S
  345. #include "tft_drivers/st7735s/setxy.h"
  346. #endif
  347. #ifndef DISABLE_ILI9341_S4P
  348. #include "tft_drivers/ili9341/s4p/setxy.h"
  349. #endif
  350. #ifndef DISABLE_ILI9341_S5P
  351. #include "tft_drivers/ili9341/s5p/setxy.h"
  352. #endif
  353. #ifndef DISABLE_R61581
  354. #include "tft_drivers/r61581/setxy.h"
  355. #endif
  356. #ifndef DISABLE_ILI9486
  357. #include "tft_drivers/ili9486/setxy.h"
  358. #endif
  359. }
  360. }
  361. void UTFT::clrXY()
  362. {
  363. if (orient==PORTRAIT)
  364. setXY(0,0,disp_x_size,disp_y_size);
  365. else
  366. setXY(0,0,disp_y_size,disp_x_size);
  367. }
  368. void UTFT::drawRect(int x1, int y1, int x2, int y2)
  369. {
  370. if (x1>x2)
  371. {
  372. swap(int, x1, x2);
  373. }
  374. if (y1>y2)
  375. {
  376. swap(int, y1, y2);
  377. }
  378. drawHLine(x1, y1, x2-x1);
  379. drawHLine(x1, y2, x2-x1);
  380. drawVLine(x1, y1, y2-y1);
  381. drawVLine(x2, y1, y2-y1);
  382. }
  383. void UTFT::drawRoundRect(int x1, int y1, int x2, int y2)
  384. {
  385. if (x1>x2)
  386. {
  387. swap(int, x1, x2);
  388. }
  389. if (y1>y2)
  390. {
  391. swap(int, y1, y2);
  392. }
  393. if ((x2-x1)>4 && (y2-y1)>4)
  394. {
  395. drawPixel(x1+1,y1+1);
  396. drawPixel(x2-1,y1+1);
  397. drawPixel(x1+1,y2-1);
  398. drawPixel(x2-1,y2-1);
  399. drawHLine(x1+2, y1, x2-x1-4);
  400. drawHLine(x1+2, y2, x2-x1-4);
  401. drawVLine(x1, y1+2, y2-y1-4);
  402. drawVLine(x2, y1+2, y2-y1-4);
  403. }
  404. }
  405. void UTFT::fillRect(int x1, int y1, int x2, int y2)
  406. {
  407. if (x1>x2)
  408. {
  409. swap(int, x1, x2);
  410. }
  411. if (y1>y2)
  412. {
  413. swap(int, y1, y2);
  414. }
  415. if (display_transfer_mode==16)
  416. {
  417. cbi(P_CS, B_CS);
  418. setXY(x1, y1, x2, y2);
  419. sbi(P_RS, B_RS);
  420. _fast_fill_16(fch,fcl,((long(x2-x1)+1)*(long(y2-y1)+1)));
  421. sbi(P_CS, B_CS);
  422. }
  423. else if ((display_transfer_mode==8) and (fch==fcl))
  424. {
  425. cbi(P_CS, B_CS);
  426. setXY(x1, y1, x2, y2);
  427. sbi(P_RS, B_RS);
  428. _fast_fill_8(fch,((long(x2-x1)+1)*(long(y2-y1)+1)));
  429. sbi(P_CS, B_CS);
  430. }
  431. else
  432. {
  433. if (orient==PORTRAIT)
  434. {
  435. for (int i=0; i<((y2-y1)/2)+1; i++)
  436. {
  437. drawHLine(x1, y1+i, x2-x1);
  438. drawHLine(x1, y2-i, x2-x1);
  439. }
  440. }
  441. else
  442. {
  443. for (int i=0; i<((x2-x1)/2)+1; i++)
  444. {
  445. drawVLine(x1+i, y1, y2-y1);
  446. drawVLine(x2-i, y1, y2-y1);
  447. }
  448. }
  449. }
  450. }
  451. void UTFT::fillRoundRect(int x1, int y1, int x2, int y2)
  452. {
  453. if (x1>x2)
  454. {
  455. swap(int, x1, x2);
  456. }
  457. if (y1>y2)
  458. {
  459. swap(int, y1, y2);
  460. }
  461. if ((x2-x1)>4 && (y2-y1)>4)
  462. {
  463. for (int i=0; i<((y2-y1)/2)+1; i++)
  464. {
  465. switch(i)
  466. {
  467. case 0:
  468. drawHLine(x1+2, y1+i, x2-x1-4);
  469. drawHLine(x1+2, y2-i, x2-x1-4);
  470. break;
  471. case 1:
  472. drawHLine(x1+1, y1+i, x2-x1-2);
  473. drawHLine(x1+1, y2-i, x2-x1-2);
  474. break;
  475. default:
  476. drawHLine(x1, y1+i, x2-x1);
  477. drawHLine(x1, y2-i, x2-x1);
  478. }
  479. }
  480. }
  481. }
  482. void UTFT::drawCircle(int x, int y, int radius)
  483. {
  484. int f = 1 - radius;
  485. int ddF_x = 1;
  486. int ddF_y = -2 * radius;
  487. int x1 = 0;
  488. int y1 = radius;
  489. cbi(P_CS, B_CS);
  490. setXY(x, y + radius, x, y + radius);
  491. LCD_Write_DATA(fch,fcl);
  492. setXY(x, y - radius, x, y - radius);
  493. LCD_Write_DATA(fch,fcl);
  494. setXY(x + radius, y, x + radius, y);
  495. LCD_Write_DATA(fch,fcl);
  496. setXY(x - radius, y, x - radius, y);
  497. LCD_Write_DATA(fch,fcl);
  498. while(x1 < y1)
  499. {
  500. if(f >= 0)
  501. {
  502. y1--;
  503. ddF_y += 2;
  504. f += ddF_y;
  505. }
  506. x1++;
  507. ddF_x += 2;
  508. f += ddF_x;
  509. setXY(x + x1, y + y1, x + x1, y + y1);
  510. LCD_Write_DATA(fch,fcl);
  511. setXY(x - x1, y + y1, x - x1, y + y1);
  512. LCD_Write_DATA(fch,fcl);
  513. setXY(x + x1, y - y1, x + x1, y - y1);
  514. LCD_Write_DATA(fch,fcl);
  515. setXY(x - x1, y - y1, x - x1, y - y1);
  516. LCD_Write_DATA(fch,fcl);
  517. setXY(x + y1, y + x1, x + y1, y + x1);
  518. LCD_Write_DATA(fch,fcl);
  519. setXY(x - y1, y + x1, x - y1, y + x1);
  520. LCD_Write_DATA(fch,fcl);
  521. setXY(x + y1, y - x1, x + y1, y - x1);
  522. LCD_Write_DATA(fch,fcl);
  523. setXY(x - y1, y - x1, x - y1, y - x1);
  524. LCD_Write_DATA(fch,fcl);
  525. }
  526. sbi(P_CS, B_CS);
  527. clrXY();
  528. }
  529. void UTFT::fillCircle(int x, int y, int radius)
  530. {
  531. for(int y1=-radius; y1<=0; y1++)
  532. for(int x1=-radius; x1<=0; x1++)
  533. if(x1*x1+y1*y1 <= radius*radius)
  534. {
  535. drawHLine(x+x1, y+y1, 2*(-x1));
  536. drawHLine(x+x1, y-y1, 2*(-x1));
  537. break;
  538. }
  539. }
  540. void UTFT::clrScr()
  541. {
  542. long i;
  543. cbi(P_CS, B_CS);
  544. clrXY();
  545. if (display_transfer_mode!=1)
  546. sbi(P_RS, B_RS);
  547. if (display_transfer_mode==16)
  548. _fast_fill_16(0,0,((disp_x_size+1)*(disp_y_size+1)));
  549. else if (display_transfer_mode==8)
  550. _fast_fill_8(0,((disp_x_size+1)*(disp_y_size+1)));
  551. else
  552. {
  553. for (i=0; i<((disp_x_size+1)*(disp_y_size+1)); i++)
  554. {
  555. if (display_transfer_mode!=1)
  556. LCD_Writ_Bus(0,0,display_transfer_mode);
  557. else
  558. {
  559. LCD_Writ_Bus(1,0,display_transfer_mode);
  560. LCD_Writ_Bus(1,0,display_transfer_mode);
  561. }
  562. }
  563. }
  564. sbi(P_CS, B_CS);
  565. }
  566. void UTFT::fillScr(byte r, byte g, byte b)
  567. {
  568. word color = ((r&248)<<8 | (g&252)<<3 | (b&248)>>3);
  569. fillScr(color);
  570. }
  571. void UTFT::fillScr(word color)
  572. {
  573. long i;
  574. char ch, cl;
  575. ch=byte(color>>8);
  576. cl=byte(color & 0xFF);
  577. cbi(P_CS, B_CS);
  578. clrXY();
  579. if (display_transfer_mode!=1)
  580. sbi(P_RS, B_RS);
  581. if (display_transfer_mode==16)
  582. _fast_fill_16(ch,cl,((disp_x_size+1)*(disp_y_size+1)));
  583. else if ((display_transfer_mode==8) and (ch==cl))
  584. _fast_fill_8(ch,((disp_x_size+1)*(disp_y_size+1)));
  585. else
  586. {
  587. for (i=0; i<((disp_x_size+1)*(disp_y_size+1)); i++)
  588. {
  589. if (display_transfer_mode!=1)
  590. LCD_Writ_Bus(ch,cl,display_transfer_mode);
  591. else
  592. {
  593. LCD_Writ_Bus(1,ch,display_transfer_mode);
  594. LCD_Writ_Bus(1,cl,display_transfer_mode);
  595. }
  596. }
  597. }
  598. sbi(P_CS, B_CS);
  599. }
  600. void UTFT::setColor(byte r, byte g, byte b)
  601. {
  602. fch=((r&248)|g>>5);
  603. fcl=((g&28)<<3|b>>3);
  604. }
  605. void UTFT::setColor(word color)
  606. {
  607. fch=byte(color>>8);
  608. fcl=byte(color & 0xFF);
  609. }
  610. word UTFT::getColor()
  611. {
  612. return (fch<<8) | fcl;
  613. }
  614. void UTFT::setBackColor(byte r, byte g, byte b)
  615. {
  616. bch=((r&248)|g>>5);
  617. bcl=((g&28)<<3|b>>3);
  618. _transparent=false;
  619. }
  620. void UTFT::setBackColor(uint32_t color)
  621. {
  622. if (color==VGA_TRANSPARENT)
  623. _transparent=true;
  624. else
  625. {
  626. bch=byte(color>>8);
  627. bcl=byte(color & 0xFF);
  628. _transparent=false;
  629. }
  630. }
  631. word UTFT::getBackColor()
  632. {
  633. return (bch<<8) | bcl;
  634. }
  635. void UTFT::setPixel(word color)
  636. {
  637. LCD_Write_DATA((color>>8),(color&0xFF)); // rrrrrggggggbbbbb
  638. }
  639. void UTFT::drawPixel(int x, int y)
  640. {
  641. cbi(P_CS, B_CS);
  642. setXY(x, y, x, y);
  643. setPixel((fch<<8)|fcl);
  644. sbi(P_CS, B_CS);
  645. clrXY();
  646. }
  647. void UTFT::drawLine(int x1, int y1, int x2, int y2)
  648. {
  649. if (y1==y2)
  650. drawHLine(x1, y1, x2-x1);
  651. else if (x1==x2)
  652. drawVLine(x1, y1, y2-y1);
  653. else
  654. {
  655. unsigned int dx = (x2 > x1 ? x2 - x1 : x1 - x2);
  656. short xstep = x2 > x1 ? 1 : -1;
  657. unsigned int dy = (y2 > y1 ? y2 - y1 : y1 - y2);
  658. short ystep = y2 > y1 ? 1 : -1;
  659. int col = x1, row = y1;
  660. cbi(P_CS, B_CS);
  661. if (dx < dy)
  662. {
  663. int t = - (dy >> 1);
  664. while (true)
  665. {
  666. setXY (col, row, col, row);
  667. LCD_Write_DATA (fch, fcl);
  668. if (row == y2)
  669. return;
  670. row += ystep;
  671. t += dx;
  672. if (t >= 0)
  673. {
  674. col += xstep;
  675. t -= dy;
  676. }
  677. }
  678. }
  679. else
  680. {
  681. int t = - (dx >> 1);
  682. while (true)
  683. {
  684. setXY (col, row, col, row);
  685. LCD_Write_DATA (fch, fcl);
  686. if (col == x2)
  687. return;
  688. col += xstep;
  689. t += dy;
  690. if (t >= 0)
  691. {
  692. row += ystep;
  693. t -= dx;
  694. }
  695. }
  696. }
  697. sbi(P_CS, B_CS);
  698. }
  699. clrXY();
  700. }
  701. void UTFT::drawHLine(int x, int y, int l)
  702. {
  703. if (l<0)
  704. {
  705. l = -l;
  706. x -= l;
  707. }
  708. cbi(P_CS, B_CS);
  709. setXY(x, y, x+l, y);
  710. if (display_transfer_mode == 16)
  711. {
  712. sbi(P_RS, B_RS);
  713. _fast_fill_16(fch,fcl,l);
  714. }
  715. else if ((display_transfer_mode==8) and (fch==fcl))
  716. {
  717. sbi(P_RS, B_RS);
  718. _fast_fill_8(fch,l);
  719. }
  720. else
  721. {
  722. for (int i=0; i<l+1; i++)
  723. {
  724. LCD_Write_DATA(fch, fcl);
  725. }
  726. }
  727. sbi(P_CS, B_CS);
  728. clrXY();
  729. }
  730. void UTFT::drawVLine(int x, int y, int l)
  731. {
  732. if (l<0)
  733. {
  734. l = -l;
  735. y -= l;
  736. }
  737. cbi(P_CS, B_CS);
  738. setXY(x, y, x, y+l);
  739. if (display_transfer_mode == 16)
  740. {
  741. sbi(P_RS, B_RS);
  742. _fast_fill_16(fch,fcl,l);
  743. }
  744. else if ((display_transfer_mode==8) and (fch==fcl))
  745. {
  746. sbi(P_RS, B_RS);
  747. _fast_fill_8(fch,l);
  748. }
  749. else
  750. {
  751. for (int i=0; i<l+1; i++)
  752. {
  753. LCD_Write_DATA(fch, fcl);
  754. }
  755. }
  756. sbi(P_CS, B_CS);
  757. clrXY();
  758. }
  759. void UTFT::printChar(byte c, int x, int y)
  760. {
  761. byte i,ch;
  762. word j;
  763. word temp;
  764. cbi(P_CS, B_CS);
  765. if (!_transparent)
  766. {
  767. if (orient==PORTRAIT)
  768. {
  769. setXY(x,y,x+cfont.x_size-1,y+cfont.y_size-1);
  770. temp=((c-cfont.offset)*((cfont.x_size/8)*cfont.y_size))+4;
  771. for(j=0;j<((cfont.x_size/8)*cfont.y_size);j++)
  772. {
  773. ch=pgm_read_byte(&cfont.font[temp]);
  774. for(i=0;i<8;i++)
  775. {
  776. if((ch&(1<<(7-i)))!=0)
  777. {
  778. setPixel((fch<<8)|fcl);
  779. }
  780. else
  781. {
  782. setPixel((bch<<8)|bcl);
  783. }
  784. }
  785. temp++;
  786. }
  787. }
  788. else
  789. {
  790. temp=((c-cfont.offset)*((cfont.x_size/8)*cfont.y_size))+4;
  791. for(j=0;j<((cfont.x_size/8)*cfont.y_size);j+=(cfont.x_size/8))
  792. {
  793. setXY(x,y+(j/(cfont.x_size/8)),x+cfont.x_size-1,y+(j/(cfont.x_size/8)));
  794. for (int zz=(cfont.x_size/8)-1; zz>=0; zz--)
  795. {
  796. ch=pgm_read_byte(&cfont.font[temp+zz]);
  797. for(i=0;i<8;i++)
  798. {
  799. if((ch&(1<<i))!=0)
  800. {
  801. setPixel((fch<<8)|fcl);
  802. }
  803. else
  804. {
  805. setPixel((bch<<8)|bcl);
  806. }
  807. }
  808. }
  809. temp+=(cfont.x_size/8);
  810. }
  811. }
  812. }
  813. else
  814. {
  815. temp=((c-cfont.offset)*((cfont.x_size/8)*cfont.y_size))+4;
  816. for(j=0;j<cfont.y_size;j++)
  817. {
  818. for (int zz=0; zz<(cfont.x_size/8); zz++)
  819. {
  820. ch=pgm_read_byte(&cfont.font[temp+zz]);
  821. for(i=0;i<8;i++)
  822. {
  823. setXY(x+i+(zz*8),y+j,x+i+(zz*8)+1,y+j+1);
  824. if((ch&(1<<(7-i)))!=0)
  825. {
  826. setPixel((fch<<8)|fcl);
  827. }
  828. }
  829. }
  830. temp+=(cfont.x_size/8);
  831. }
  832. }
  833. sbi(P_CS, B_CS);
  834. clrXY();
  835. }
  836. void UTFT::rotateChar(byte c, int x, int y, int pos, int deg)
  837. {
  838. byte i,j,ch;
  839. word temp;
  840. int newx,newy;
  841. double radian;
  842. radian=deg*0.0175;
  843. cbi(P_CS, B_CS);
  844. temp=((c-cfont.offset)*((cfont.x_size/8)*cfont.y_size))+4;
  845. for(j=0;j<cfont.y_size;j++)
  846. {
  847. for (int zz=0; zz<(cfont.x_size/8); zz++)
  848. {
  849. ch=pgm_read_byte(&cfont.font[temp+zz]);
  850. for(i=0;i<8;i++)
  851. {
  852. newx=x+(((i+(zz*8)+(pos*cfont.x_size))*cos(radian))-((j)*sin(radian)));
  853. newy=y+(((j)*cos(radian))+((i+(zz*8)+(pos*cfont.x_size))*sin(radian)));
  854. setXY(newx,newy,newx+1,newy+1);
  855. if((ch&(1<<(7-i)))!=0)
  856. {
  857. setPixel((fch<<8)|fcl);
  858. }
  859. else
  860. {
  861. if (!_transparent)
  862. setPixel((bch<<8)|bcl);
  863. }
  864. }
  865. }
  866. temp+=(cfont.x_size/8);
  867. }
  868. sbi(P_CS, B_CS);
  869. clrXY();
  870. }
  871. void UTFT::print(const char *st, int x, int y, int deg)
  872. {
  873. int stl, i;
  874. stl = strlen(st);
  875. if (orient==PORTRAIT)
  876. {
  877. if (x==RIGHT)
  878. x=(disp_x_size+1)-(stl*cfont.x_size);
  879. if (x==CENTER)
  880. x=((disp_x_size+1)-(stl*cfont.x_size))/2;
  881. }
  882. else
  883. {
  884. if (x==RIGHT)
  885. x=(disp_y_size+1)-(stl*cfont.x_size);
  886. if (x==CENTER)
  887. x=((disp_y_size+1)-(stl*cfont.x_size))/2;
  888. }
  889. for (i=0; i<stl; i++)
  890. if (deg==0)
  891. printChar(*st++, x + (i*(cfont.x_size)), y);
  892. else
  893. rotateChar(*st++, x, y, i, deg);
  894. }
  895. void UTFT::print(String st, int x, int y, int deg)
  896. {
  897. char buf[st.length()+1];
  898. st.toCharArray(buf, st.length()+1);
  899. print(buf, x, y, deg);
  900. }
  901. void UTFT::printNumI(long num, int x, int y, int length, char filler)
  902. {
  903. char buf[25];
  904. char st[27];
  905. boolean neg=false;
  906. int c=0, f=0;
  907. if (num==0)
  908. {
  909. if (length!=0)
  910. {
  911. for (c=0; c<(length-1); c++)
  912. st[c]=filler;
  913. st[c]=48;
  914. st[c+1]=0;
  915. }
  916. else
  917. {
  918. st[0]=48;
  919. st[1]=0;
  920. }
  921. }
  922. else
  923. {
  924. if (num<0)
  925. {
  926. neg=true;
  927. num=-num;
  928. }
  929. while (num>0)
  930. {
  931. buf[c]=48+(num % 10);
  932. c++;
  933. num=(num-(num % 10))/10;
  934. }
  935. buf[c]=0;
  936. if (neg)
  937. {
  938. st[0]=45;
  939. }
  940. if (length>(c+neg))
  941. {
  942. for (int i=0; i<(length-c-neg); i++)
  943. {
  944. st[i+neg]=filler;
  945. f++;
  946. }
  947. }
  948. for (int i=0; i<c; i++)
  949. {
  950. st[i+neg+f]=buf[c-i-1];
  951. }
  952. st[c+neg+f]=0;
  953. }
  954. print(st,x,y);
  955. }
  956. void UTFT::printNumF(double num, byte dec, int x, int y, char divider, int length, char filler)
  957. {
  958. char st[27];
  959. boolean neg=false;
  960. if (dec<1)
  961. dec=1;
  962. else if (dec>5)
  963. dec=5;
  964. if (num<0)
  965. neg = true;
  966. _convert_float(st, num, length, dec);
  967. if (divider != '.')
  968. {
  969. for (int i=0; i<(int)sizeof(st); i++)
  970. if (st[i]=='.')
  971. st[i]=divider;
  972. }
  973. if (filler != ' ')
  974. {
  975. if (neg)
  976. {
  977. st[0]='-';
  978. for (int i=1; i<(int)sizeof(st); i++)
  979. if ((st[i]==' ') || (st[i]=='-'))
  980. st[i]=filler;
  981. }
  982. else
  983. {
  984. for (int i=0; i<(int)sizeof(st); i++)
  985. if (st[i]==' ')
  986. st[i]=filler;
  987. }
  988. }
  989. print(st,x,y);
  990. }
  991. void UTFT::setFont(uint8_t* font)
  992. {
  993. cfont.font=font;
  994. cfont.x_size=fontbyte(0);
  995. cfont.y_size=fontbyte(1);
  996. cfont.offset=fontbyte(2);
  997. cfont.numchars=fontbyte(3);
  998. }
  999. uint8_t* UTFT::getFont()
  1000. {
  1001. return cfont.font;
  1002. }
  1003. uint8_t UTFT::getFontXsize()
  1004. {
  1005. return cfont.x_size;
  1006. }
  1007. uint8_t UTFT::getFontYsize()
  1008. {
  1009. return cfont.y_size;
  1010. }
  1011. void UTFT::drawBitmap(int x, int y, int sx, int sy, bitmapdatatype data, int scale)
  1012. {
  1013. unsigned int col;
  1014. int tx, ty, tc, tsx, tsy;
  1015. if (scale==1)
  1016. {
  1017. if (orient==PORTRAIT)
  1018. {
  1019. cbi(P_CS, B_CS);
  1020. setXY(x, y, x+sx-1, y+sy-1);
  1021. for (tc=0; tc<(sx*sy); tc++)
  1022. {
  1023. col=pgm_read_word(&data[tc]);
  1024. LCD_Write_DATA(col>>8,col & 0xff);
  1025. }
  1026. sbi(P_CS, B_CS);
  1027. }
  1028. else
  1029. {
  1030. cbi(P_CS, B_CS);
  1031. for (ty=0; ty<sy; ty++)
  1032. {
  1033. setXY(x, y+ty, x+sx-1, y+ty);
  1034. for (tx=sx-1; tx>=0; tx--)
  1035. {
  1036. col=pgm_read_word(&data[(ty*sx)+tx]);
  1037. LCD_Write_DATA(col>>8,col & 0xff);
  1038. }
  1039. }
  1040. sbi(P_CS, B_CS);
  1041. }
  1042. }
  1043. else
  1044. {
  1045. if (orient==PORTRAIT)
  1046. {
  1047. cbi(P_CS, B_CS);
  1048. for (ty=0; ty<sy; ty++)
  1049. {
  1050. setXY(x, y+(ty*scale), x+((sx*scale)-1), y+(ty*scale)+scale);
  1051. for (tsy=0; tsy<scale; tsy++)
  1052. for (tx=0; tx<sx; tx++)
  1053. {
  1054. col=pgm_read_word(&data[(ty*sx)+tx]);
  1055. for (tsx=0; tsx<scale; tsx++)
  1056. LCD_Write_DATA(col>>8,col & 0xff);
  1057. }
  1058. }
  1059. sbi(P_CS, B_CS);
  1060. }
  1061. else
  1062. {
  1063. cbi(P_CS, B_CS);
  1064. for (ty=0; ty<sy; ty++)
  1065. {
  1066. for (tsy=0; tsy<scale; tsy++)
  1067. {
  1068. setXY(x, y+(ty*scale)+tsy, x+((sx*scale)-1), y+(ty*scale)+tsy);
  1069. for (tx=sx-1; tx>=0; tx--)
  1070. {
  1071. col=pgm_read_word(&data[(ty*sx)+tx]);
  1072. for (tsx=0; tsx<scale; tsx++)
  1073. LCD_Write_DATA(col>>8,col & 0xff);
  1074. }
  1075. }
  1076. }
  1077. sbi(P_CS, B_CS);
  1078. }
  1079. }
  1080. clrXY();
  1081. }
  1082. void UTFT::drawBitmap(int x, int y, int sx, int sy, bitmapdatatype data, int deg, int rox, int roy)
  1083. {
  1084. unsigned int col;
  1085. int tx, ty, newx, newy;
  1086. double radian;
  1087. radian=deg*0.0175;
  1088. if (deg==0)
  1089. drawBitmap(x, y, sx, sy, data);
  1090. else
  1091. {
  1092. cbi(P_CS, B_CS);
  1093. for (ty=0; ty<sy; ty++)
  1094. for (tx=0; tx<sx; tx++)
  1095. {
  1096. col=pgm_read_word(&data[(ty*sx)+tx]);
  1097. newx=x+rox+(((tx-rox)*cos(radian))-((ty-roy)*sin(radian)));
  1098. newy=y+roy+(((ty-roy)*cos(radian))+((tx-rox)*sin(radian)));
  1099. setXY(newx, newy, newx, newy);
  1100. LCD_Write_DATA(col>>8,col & 0xff);
  1101. }
  1102. sbi(P_CS, B_CS);
  1103. }
  1104. clrXY();
  1105. }
  1106. void UTFT::lcdOff()
  1107. {
  1108. cbi(P_CS, B_CS);
  1109. switch (display_model)
  1110. {
  1111. case PCF8833:
  1112. LCD_Write_COM(0x28);
  1113. break;
  1114. }
  1115. sbi(P_CS, B_CS);
  1116. }
  1117. void UTFT::lcdOn()
  1118. {
  1119. cbi(P_CS, B_CS);
  1120. switch (display_model)
  1121. {
  1122. case PCF8833:
  1123. LCD_Write_COM(0x29);
  1124. break;
  1125. }
  1126. sbi(P_CS, B_CS);
  1127. }
  1128. void UTFT::setContrast(char c)
  1129. {
  1130. cbi(P_CS, B_CS);
  1131. switch (display_model)
  1132. {
  1133. case PCF8833:
  1134. if (c>64) c=64;
  1135. LCD_Write_COM(0x25);
  1136. LCD_Write_DATA(c);
  1137. break;
  1138. }
  1139. sbi(P_CS, B_CS);
  1140. }
  1141. int UTFT::getDisplayXSize()
  1142. {
  1143. if (orient==PORTRAIT)
  1144. return disp_x_size+1;
  1145. else
  1146. return disp_y_size+1;
  1147. }
  1148. int UTFT::getDisplayYSize()
  1149. {
  1150. if (orient==PORTRAIT)
  1151. return disp_y_size+1;
  1152. else
  1153. return disp_x_size+1;
  1154. }