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.

1132 lines
48KB

  1. /*
  2. --------------------------------------------------
  3. RA8875 LCD/TFT Graphic Controller Driver Library
  4. --------------------------------------------------
  5. Version:0.70b11p11
  6. ++++++++++++++++++++++++++++++++++++++++++++++++++
  7. Written by: Max MC Costa for s.u.m.o.t.o.y
  8. ++++++++++++++++++++++++++++++++++++++++++++++++++
  9. An attemp to create a full featured library support for RA8875 chip from RAiO.
  10. Works with many SPI drived RA8875 Boards included Adafruit, Eastrising(buydisplay).
  11. NOT work if you have a I2C or Parallel based display!
  12. -------------------------------------------------------------------------------------
  13. >>>>>>>>>>>> About Copyrights <<<<<<<<<<<<<<<
  14. -------------------------------------------------------------------------------------
  15. License:GNU General Public License v3.0
  16. RA8875 fast SPI library for RAiO SPI RA8875 drived TFT
  17. Copyright (C) 2014 egidio massimo costa sumotoy (a t) gmail.com
  18. This program is free software: you can redistribute it and/or modify
  19. it under the terms of the GNU General Public License as published by
  20. the Free Software Foundation, either version 3 of the License, or
  21. (at your option) any later version.
  22. This program is distributed in the hope that it will be useful,
  23. but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25. GNU General Public License for more details.
  26. You should have received a copy of the GNU General Public License
  27. along with this program. If not, see <http://www.gnu.org/licenses/>.
  28. -------------------------------------------------------------------------------------
  29. >>>>>>>>>>>> Thanks to <<<<<<<<<<<<<<<
  30. -------------------------------------------------------------------------------------
  31. Teensy 3.1, a tiny MCU but monster of performances at tiny price, Arduino should learn...
  32. Paul Stoffregen, the 'guru' behind many arduino magic, the father of Teensy
  33. Bill Greyman, another 'maestro', greatly inspired many coders
  34. Jnmattern & Marek Buriak for drawArc
  35. Last but not less important the contributors and beta tester of this library:
  36. M.Sandercrock, the experimentalist, MrTom and many others
  37. -------------------------------------------------------------------------------------
  38. >>>>>>>>>>>> Current version notes <<<<<<<<<<<<<<<
  39. -------------------------------------------------------------------------------------
  40. 0.70b11p8 changes: Fixed some small error (thanks Mr TOM) that affects drawLine
  41. and drawLineAngle. Initial support for SPARK devices (very early development)
  42. Fixed a couple of examples.
  43. 0.70b11p9 changes: Now compile with particle spark! But spark development toolchain it's a nightmare so
  44. use https://github.com/sumotoy/spark_ra8875
  45. 0.70b11p10: Some changes proposed by MrTom to fix the triangle hardware bug of RA8875
  46. 0.70b11p11: Minor changes on triangles helper (MrTom)
  47. -------------------------------------------------------------------------------------
  48. >>>>>>>>>>>>>>>>>>>>> Wiring <<<<<<<<<<<<<<<<<<<<<<<<<
  49. -------------------------------------------------------------------------------------
  50. TFT side Teensy/Uno
  51. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  52. CLK: pin 13 UNO
  53. MOSI: pin 11 UNO
  54. MISO: pin 12 UNO
  55. CS: pin 10 (selectable but note 1*!)
  56. INT: pin 2 (selectable 2*)
  57. RESET: pin 9 (selectable and optional 0*)
  58. *(0) In some modules you can leave unconnected but check if it's needed!
  59. *(1) On Teensy3.x not all pin are usable for CS! Read the printed paper
  60. that come with your Teensy3.x for more informations!
  61. *(2) Arduino cannot use any pin for interrupts! In my examples I don't use
  62. interrupts but just reading pin state so you can use any pin :)
  63. -------------------------------------------------------------------------------------
  64. TFT side Stellaris (LM4F120XL) module=0 (still not checked)
  65. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  66. CLK: xxx
  67. MOSI: xxx
  68. MISO: xxx
  69. CS: xxx (selectable)
  70. INT: xxx (selectable)
  71. RESET: xxx (selectable and optional)
  72. *if you use an [optional] SD card here's connections...
  73. -------------------------------------------------------------------------------------
  74. TFT side Teensy2/Teensy3/Uno
  75. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  76. SD CLK: pin 13 [shared with RA]
  77. SD MOSI: pin 11 [shared with RA]
  78. SD MISO: pin 12 [shared with RA]
  79. SD CS: pin 4 (selectable 3*)
  80. SD CARD ID: pin xx (selectable and optional)
  81. *(3) On Teensy3.x not all pin are usable for CS!
  82. can be used: 2,6,9,10,15,20,21,22,23
  83. -------------------------------------------------------------------------------------
  84. TFT side Stellaris (LM4F120XL) module=0 (still not checked)
  85. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  86. SD CLK: xxx shared
  87. SD MOSI: xxx shared
  88. SD MISO: xxx shared
  89. SD CS: xxx (selectable)
  90. SD CARD ID: pin xx (selectable and optional)
  91. -------------------------------------------------------------------------------------
  92. TFT side Teensy3 alternative setup
  93. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  94. There are special cases on Teensy 3.x since it can be used for audio shield that remap
  95. some pin. Using SPI in that situation will be impossible but you can use the alternative
  96. pins definition feature of Teensy 3!
  97. SD CLK: pin 13(normal),pin 14(alt) [shared with RA]
  98. SD MOSI: pin 11(normal),pin 7(alt) [shared with RA]
  99. SD MISO: pin 12(normal),pin 8(alt) [shared with RA]
  100. SD CS: pin 2 (selectable 3*)
  101. SD CARD ID: pin xx (selectable and optional)
  102. *(3) On Teensy3.x not all pin are usable for CS's!
  103. can be used: 2,6,9,10,15,20,21,22,23
  104. -------------------------------------------------------------------------------------
  105. TFT side Particle Spark (caution, never tested!)
  106. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  107. CLK: A3
  108. MOSI: A5
  109. MISO: A4
  110. CS: A2
  111. INT:
  112. SDA: D0
  113. SCL: D1
  114. Benchmark results for reference --------------------------------------
  115. Screen fill 16635 16585 16561 8326
  116. Test Pixel 60 77 63 53
  117. Test Pixels 39780 52085 41885 35412
  118. Text 4500 4389 4634 3409
  119. Lines 96705 101951 97943 55986
  120. Horiz/Vert Lines 66656 72470 67732 42703
  121. Rectangles (outline) 269786 271251 269987 137691
  122. Rectangles (filled) 269498 271415 270002 137858
  123. Circles (filled) 110285 195011 181003 117279
  124. Circles (outline) 109604 191746 177459 115584
  125. Triangles (outline) 24521 26320 24886 14728
  126. Triangles (filled) 64947 66801 65367 35226
  127. Rounded rects (outline) 146391 167477 151142 103027
  128. Rounded rects (filled) 935691 953280 940016 493179
  129. PIN UNO MEGA CD4050 RA8875
  130. SCK 13 52 YES SCK
  131. MOSI 11 51 YES MOSI
  132. MISO 12 50 NO MISO
  133. RST 9 5 YES RST
  134. CS 10 53 YES CS
  135. */
  136. #ifndef _RA8875MC_H_
  137. #define _RA8875MC_H_
  138. #include <inttypes.h>
  139. #if !defined(swapvals)
  140. #if defined(ESP8266)
  141. #define swapvals(a, b) { int16_t t = a; a = b; b = t; }
  142. //#define swapvals(a, b) { typeid(a) t = a; a = b; b = t; }
  143. #else
  144. #define swapvals(a, b) { typeof(a) t = a; a = b; b = t; }
  145. #endif
  146. #endif
  147. enum RA8875sizes { RA8875_480x272, RA8875_800x480, RA8875_800x480ALT, Adafruit_480x272, Adafruit_800x480 };
  148. enum RA8875tcursor { NOCURSOR=0,IBEAM,UNDER,BLOCK };//0,1,2,3
  149. enum RA8875tsize { X16=0,X24,X32 };//0,1,2
  150. enum RA8875fontSource { INTFONT=0, EXTFONT };//0,1
  151. enum RA8875fontCoding { ISO_IEC_8859_1, ISO_IEC_8859_2, ISO_IEC_8859_3, ISO_IEC_8859_4 };
  152. enum RA8875extRomType { GT21L16T1W, GT21H16T1W, GT23L16U2W, GT30L16U2W, GT30H24T3Y, GT23L24T3Y, GT23L24M1Z, GT23L32S4W, GT30H32S4W, GT30L32S4W, ER3303_1, ER3304_1, ER3301_1 };
  153. enum RA8875extRomCoding { GB2312, GB12345, BIG5, UNICODE, ASCII, UNIJIS, JIS0208, LATIN };
  154. enum RA8875extRomFamily { STANDARD, ARIAL, ROMAN, BOLD };
  155. enum RA8875boolean { LAYER1, LAYER2, TRANSPARENT, LIGHTEN, OR, AND, FLOATING };
  156. enum RA8875writes { L1=0, L2, CGRAM, PATTERN, CURSOR };
  157. enum RA8875scrollMode{ SIMULTANEOUS, LAYER1ONLY, LAYER2ONLY, BUFFERED };
  158. enum RA8875pattern{ P8X8, P16X16 };
  159. enum RA8875btedatam{ CONT, RECT };
  160. enum RA8875btelayer{ SOURCE, DEST };
  161. enum RA8875intlist{ BTE=1,TOUCH=2, DMA=3,KEY=4 };
  162. /*
  163. -------------- UNICODE decode (2 byte char) ---------------------
  164. Latin: \u0000 -> \u007F /u00
  165. Greek: \u0370 -> \u03FF /u03
  166. Cyrillic: \u0400 -> \u04FF /u04
  167. Hebrew: \u0590 -> \u05FF /u05
  168. Arabic: \u0600 -> \u06FF /u06
  169. Hiragana: \u3040 -> \u309F /u30
  170. Katakana: \u30A0 -> \u30FF /u30
  171. CJK-Uni: \u4E00 -> \u9FD5 /u4E ... /u9F
  172. */
  173. /* ----------------------------DO NOT TOUCH ANITHING FROM HERE ------------------------*/
  174. // Documentation on the ILI9488_t3 font data format:
  175. // https://forum.pjrc.com/threads/54316-ILI9488_t-font-structure-format
  176. /*
  177. typedef struct {
  178. const unsigned char *index;
  179. const unsigned char *unicode;
  180. const unsigned char *data;
  181. unsigned char version;
  182. unsigned char reserved;
  183. unsigned char index1_first;
  184. unsigned char index1_last;
  185. unsigned char index2_first;
  186. unsigned char index2_last;
  187. unsigned char bits_index;
  188. unsigned char bits_width;
  189. unsigned char bits_height;
  190. unsigned char bits_xoffset;
  191. unsigned char bits_yoffset;
  192. unsigned char bits_delta;
  193. unsigned char line_space;
  194. unsigned char cap_height;
  195. } ILI9341_t3_font_t;
  196. */
  197. #include "ILI9341_fonts.h"
  198. // Lets see about supporting Adafruit fonts as well?
  199. #if __has_include(<gfxfont.h>)
  200. #include <gfxfont.h>
  201. #endif
  202. #ifndef _GFXFONT_H_
  203. #define _GFXFONT_H_
  204. /// Font data stored PER GLYPH
  205. typedef struct {
  206. uint16_t bitmapOffset; ///< Pointer into GFXfont->bitmap
  207. uint8_t width; ///< Bitmap dimensions in pixels
  208. uint8_t height; ///< Bitmap dimensions in pixels
  209. uint8_t xAdvance; ///< Distance to advance cursor (x axis)
  210. int8_t xOffset; ///< X dist from cursor pos to UL corner
  211. int8_t yOffset; ///< Y dist from cursor pos to UL corner
  212. } GFXglyph;
  213. /// Data stored for FONT AS A WHOLE
  214. typedef struct {
  215. uint8_t *bitmap; ///< Glyph bitmaps, concatenated
  216. GFXglyph *glyph; ///< Glyph array
  217. uint8_t first; ///< ASCII extents (first char)
  218. uint8_t last; ///< ASCII extents (last char)
  219. uint8_t yAdvance; ///< Newline distance (y axis)
  220. } GFXfont;
  221. #endif // _GFXFONT_H_
  222. #ifdef __cplusplus
  223. #include "_includes/RA8875_CPU_commons.h"
  224. #include "_includes/font.h"
  225. #include "_includes/RA8875Registers.h"
  226. #include "_includes/RA8875ColorPresets.h"
  227. #include "_settings/RA8875UserSettings.h"
  228. #if !defined(_AVOID_TOUCHSCREEN) && defined(USE_FT5206_TOUCH)
  229. #include <Wire.h>
  230. #endif
  231. #if defined(_FORCE_PROGMEM__) && !defined(ESP8266)
  232. template <typename T> T PROGMEM_read (const T * sce)
  233. {
  234. static T temp;
  235. memcpy_P (&temp, sce, sizeof (T));
  236. return temp;
  237. }
  238. #endif
  239. #if defined(ESP8266) && defined(_FASTSSPORT)
  240. #include <eagle_soc.h>
  241. #endif
  242. class RA8875 : public Print
  243. {
  244. public:
  245. // void debugData(uint16_t data,uint8_t len=8);
  246. // void showLineBuffer(uint8_t data[],int len);
  247. //------------- INSTANCE -------------------------------------------------------------------
  248. #if defined(__MK20DX128__) || defined(__MK20DX256__)
  249. RA8875(const uint8_t CSp,const uint8_t RSTp=255,const uint8_t mosi_pin=11,const uint8_t sclk_pin=13,const uint8_t miso_pin=12);
  250. #elif defined(__MKL26Z64__)//TeensyLC
  251. RA8875(const uint8_t CSp,const uint8_t RSTp=255,const uint8_t mosi_pin=11,const uint8_t sclk_pin=13,const uint8_t miso_pin=12);
  252. #elif defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__)
  253. RA8875(const uint8_t CSp,const uint8_t RSTp=255,const uint8_t mosi_pin=11,const uint8_t sclk_pin=13,const uint8_t miso_pin=12);
  254. #elif defined(___DUESTUFF)//DUE
  255. RA8875(const uint8_t CSp, const uint8_t RSTp=255);
  256. #elif defined(SPARK)//SPARK
  257. RA8875(const uint8_t CSp, const uint8_t RSTp=255);
  258. #elif defined(NEEDS_SET_MODULE)//ENERGIA
  259. RA8875::RA8875(const uint8_t module, const uint8_t RSTp=255);
  260. #else//8 BIT ARDUINO's
  261. RA8875(const uint8_t CSp, const uint8_t RSTp=255);
  262. #endif
  263. //------------- SETUP -----------------------------------------------------------------------
  264. void begin(const enum RA8875sizes s,uint8_t colors=16, uint32_t SPIMaxSpeed = (uint32_t)-1, uint32_t SPIMaxReadSpeed = (uint32_t)-1 );
  265. //(RA8875_480x272, RA8875_800x480, Adafruit_480x272, Adafruit_800x480) , (8/16 bit)
  266. //------------- HARDWARE ------------------------------------------------------------
  267. void backlight(boolean on);
  268. void displayOn(boolean on);//turn diplay on/off
  269. void sleep(boolean sleep);//put display in sleep or not
  270. void brightness(uint8_t val);//ok
  271. uint8_t readStatus(void);//used to verify when an operation has concluded
  272. void clearMemory(bool stop=false);
  273. void clearWidthColor(bool bte);
  274. //void clearMemory(boolean full);//clear the RA8875 internal buffer (fully or current layer)
  275. uint8_t errorCode(void);//0: no error,
  276. /*
  277. format: 1byte 0b00000000;, bit described below:
  278. nan,nan,nan,nan,nan,CS(out-of-range),MOSI/MISO/SCLK(out-of-range),display(not-recognized)
  279. */
  280. //------------ Low Level functions ---------------------------------------------------------
  281. void writeCommand(const uint8_t d);
  282. void writeData16(uint16_t data);
  283. //Hack fonts
  284. // setOrigin sets an offset in display pixels where drawing to (0,0) will appear
  285. // for example: setOrigin(10,10); drawPixel(5,5); will cause a pixel to be drawn at hardware pixel (15,15)
  286. void setOrigin(int16_t x = 0, int16_t y = 0) {
  287. _originx = x; _originy = y;
  288. //if (Serial) Serial.printf("Set Origin %d %d\n", x, y);
  289. updateDisplayClip();
  290. }
  291. void getOrigin(int16_t* x, int16_t* y) { *x = _originx; *y = _originy; }
  292. // setClipRect() sets a clipping rectangle (relative to any set origin) for drawing to be limited to.
  293. // Drawing is also restricted to the bounds of the display
  294. void setClipRect(int16_t x1, int16_t y1, int16_t w, int16_t h)
  295. { _clipx1 = x1; _clipy1 = y1; _clipx2 = x1+w; _clipy2 = y1+h;
  296. //if (Serial) Serial.printf("Set clip Rect %d %d %d %d\n", x1, y1, w, h);
  297. updateDisplayClip();
  298. }
  299. void setClipRect() {
  300. _clipx1 = 0; _clipy1 = 0; _clipx2 = _width; _clipy2 = _height;
  301. //if (Serial) Serial.printf("clear clip Rect\n");
  302. updateDisplayClip();
  303. }
  304. bool _invisible = false;
  305. bool _standard = true; // no bounding rectangle or origin set.
  306. inline void updateDisplayClip() {
  307. _displayclipx1 = max(0,min(_clipx1+_originx,width()));
  308. _displayclipx2 = max(0,min(_clipx2+_originx,width()));
  309. _displayclipy1 = max(0,min(_clipy1+_originy,height()));
  310. _displayclipy2 = max(0,min(_clipy2+_originy,height()));
  311. _invisible = (_displayclipx1 == _displayclipx2 || _displayclipy1 == _displayclipy2);
  312. _standard = (_displayclipx1 == 0) && (_displayclipx2 == _width) && (_displayclipy1 == 0) && (_displayclipy2 == _height);
  313. if (Serial) {
  314. //Serial.printf("UDC (%d %d)-(%d %d) %d %d\n", _displayclipx1, _displayclipy1, _displayclipx2,
  315. // _displayclipy2, _invisible, _standard);
  316. }
  317. }
  318. inline void setFontDefault() {
  319. _use_default = 1;
  320. if(_portrait && (!_use_gfx_font || !_use_ili_font)) {
  321. _cursorX += _cursorY;
  322. _cursorY -= _cursorX;
  323. }
  324. _use_ili_font=0;
  325. _use_gfx_font=0;
  326. _use_int_font=1;
  327. _use_tfont=0;
  328. setActiveWindow();
  329. _textPosition(_cursorX, _cursorY, false);
  330. };
  331. void setFont(const ILI9341_t3_font_t &f);
  332. void setFont(const GFXfont *f = NULL);
  333. void setFontAdafruit(void) { setFont(); }
  334. void drawFontChar(unsigned int c);
  335. void drawGFXFontChar(unsigned int c);
  336. void setTextSize(uint8_t sx, uint8_t sy);
  337. void inline setTextSize(uint8_t s) { setTextSize(s,s); }
  338. void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size_x, uint8_t size_y);
  339. void inline drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size)
  340. { drawChar(x, y, c, color, bg, size);}
  341. void drawFontBits(bool opaque, uint32_t bits, uint32_t numbits, int32_t x, int32_t y, uint32_t repeat);
  342. void Pixel(int16_t x, int16_t y, uint16_t color);
  343. void charBounds(char c, int16_t *x, int16_t *y,
  344. int16_t *minx, int16_t *miny, int16_t *maxx, int16_t *maxy);
  345. void getTextBounds(const uint8_t *buffer, uint16_t len, int16_t x, int16_t y,
  346. int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
  347. void getTextBounds(const char *string, int16_t x, int16_t y,
  348. int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
  349. void getTextBounds(const String &str, int16_t x, int16_t y,
  350. int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
  351. int16_t strPixelLen(const char * str);
  352. void drawFontPixel( uint8_t alpha, uint32_t x, uint32_t y );
  353. void write16BitColor(uint16_t color, bool last_pixel=false);
  354. // Hack to see about combining outputs for speed.
  355. int16_t _combine_x_start = 0;
  356. int16_t _combine_y = 0;
  357. int16_t _combine_count = 0;
  358. uint16_t _combine_color = 0;
  359. inline void combineAndDrawPixel(int16_t x, int16_t y, uint16_t color) {
  360. if (_combine_count && (color == _combine_color)) _combine_count++;
  361. else {
  362. if (_combine_count)drawLine(_combine_x_start, _combine_y, _combine_x_start+_combine_count-1, _combine_y, _combine_color);
  363. _combine_x_start = x;
  364. _combine_y = y;
  365. _combine_count = 1;
  366. _combine_color = color;
  367. }
  368. }
  369. inline void forceCombinedPixelsOut() {
  370. if (_combine_count)fillRect(_combine_x_start, _combine_y, _combine_count, 1, _combine_color);
  371. _combine_count = 0;
  372. }
  373. //-------------- AREA ----------------------------------------------------------------------
  374. void setActiveWindow(int16_t XL,int16_t XR,int16_t YT,int16_t YB);//The working area where to draw on
  375. void setActiveWindow(void);
  376. void getActiveWindow(int16_t &XL,int16_t &XR ,int16_t &YT ,int16_t &YB);
  377. void clearActiveWindow(bool full=false);//it clears the active window
  378. uint16_t width(bool absolute=false) const;//the phisical display width
  379. uint16_t height(bool absolute=false) const;//the phisical display height
  380. void setRotation(uint8_t rotation); //rotate text and graphics
  381. uint8_t getRotation(); //return the current rotation 0-3
  382. boolean isPortrait(void);
  383. //-------------- COLOR ----------------------------------------------------------------------
  384. void setForegroundColor(uint16_t color);//color of objects in 16bit
  385. void setForegroundColor(uint8_t R,uint8_t G,uint8_t B);//color of objects in 8+8+8bit
  386. void setBackgroundColor(uint16_t color);//color of objects background in 16bit
  387. void setBackgroundColor(uint8_t R,uint8_t G,uint8_t B);//color of objects background in 8+8+8bit
  388. void setTransparentColor(uint16_t color);//the current transparent color in 16bit
  389. void setTransparentColor(uint8_t R,uint8_t G,uint8_t B);//the current transparent color in 8+8+8bit
  390. void setColor(uint16_t fcolor,uint16_t bcolor,bool bcolorTraspFlag=false);
  391. void setColorBpp(uint8_t colors);//set the display color space 8 or 16!
  392. uint8_t getColorBpp(void);//get the current display color space (return 8 or 16)
  393. uint16_t grandient(uint8_t val);
  394. uint16_t colorInterpolation(uint16_t color1,uint16_t color2,uint16_t pos,uint16_t div=100);
  395. uint16_t colorInterpolation(uint8_t r1,uint8_t g1,uint8_t b1,uint8_t r2,uint8_t g2,uint8_t b2,uint16_t pos,uint16_t div=100);
  396. //-------------- COLOR CONVERSION -----------------------------------------------------------
  397. inline uint16_t Color565(uint8_t r,uint8_t g,uint8_t b) { return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); }
  398. inline uint16_t Color24To565(int32_t color_) { return ((((color_ >> 16) & 0xFF) / 8) << 11) | ((((color_ >> 8) & 0xFF) / 4) << 5) | (((color_) & 0xFF) / 8);}
  399. inline uint16_t htmlTo565(int32_t color_) { return (uint16_t)(((color_ & 0xF80000) >> 8) | ((color_ & 0x00FC00) >> 5) | ((color_ & 0x0000F8) >> 3));}
  400. inline void Color565ToRGB(uint16_t color, uint8_t &r, uint8_t &g, uint8_t &b){r = (((color & 0xF800) >> 11) * 527 + 23) >> 6; g = (((color & 0x07E0) >> 5) * 259 + 33) >> 6; b = ((color & 0x001F) * 527 + 23) >> 6;}
  401. //-------------- CURSOR ----------------------------------------------------------------------
  402. void cursorIncrement(bool on);
  403. void setCursorBlinkRate(uint8_t rate);//set blink rate of the cursor 0...255 0:faster
  404. void showCursor(enum RA8875tcursor c,bool blink);//show cursor(NOCURSOR,IBEAM,UNDER,BLOCK), default blinking
  405. void setCursor(int16_t x, int16_t y,bool autocenter=false);//set cursor position to write text(pixels or CENTER)
  406. void getCursor(int16_t &x, int16_t &y);//from the RA8875 registers
  407. void getCursorFast(int16_t &x, int16_t &y);//from library (faster)
  408. int16_t getCursorX(void);
  409. int16_t getCursorY(void);
  410. void setGraphicCursor(uint8_t cur);//0...7 Select a custom graphic cursor (you should upload first)
  411. void showGraphicCursor(boolean cur);//show graphic cursor
  412. //-------------- TEXT -----------------------------------------------------------------------
  413. void uploadUserChar(const uint8_t symbol[],uint8_t address);//upload user defined char as array at the address 0..255
  414. void showUserChar(uint8_t symbolAddrs,uint8_t wide=0);//show user uploaded char at the adrs 0...255
  415. void setTextColor(uint16_t fcolor, uint16_t bcolor);//set text color + text background color
  416. void setTextColor(uint16_t fcolor);//set text color (backgroud will be transparent)
  417. void setTextGrandient(uint16_t fcolor1,uint16_t fcolor2);
  418. void setFontScale(uint8_t scale);//global font scale (w+h)
  419. void setFontScale(uint8_t xscale,uint8_t yscale);//font scale separated by w and h
  420. void setFontSize(enum RA8875tsize ts);//X16,X24,X32
  421. void setFontSpacing(uint8_t spc);//0:disabled ... 63:pix max
  422. void setFontInterline(uint8_t pix);//0...63 pix
  423. void setFontFullAlign(boolean align);//mmmm... doesn't do nothing! Have to investigate
  424. uint8_t getFontWidth(boolean inColums=false);
  425. uint8_t getFontHeight(boolean inRows=false);
  426. //----------FONT -------------------------------------------------------------------------
  427. void setExternalFontRom(enum RA8875extRomType ert, enum RA8875extRomCoding erc,enum RA8875extRomFamily erf=STANDARD);
  428. void setFont(enum RA8875fontSource s);//INTFONT,EXTFONT (if you have a chip installed)
  429. //void setFont(const struct FONT_DEF * fnt);
  430. void setFont(const tFont *font);
  431. void setIntFontCoding(enum RA8875fontCoding f);
  432. void setExtFontFamily(enum RA8875extRomFamily erf,boolean setReg=true);
  433. //-------------- GRAPHIC POSITION --------------------------------------------------------------
  434. void setXY(int16_t x, int16_t y);//graphic set location
  435. void setX(int16_t x);
  436. void setY(int16_t y) ;
  437. //--------------- DRAW ---------------------------------------------------------------------
  438. void drawPixel(int16_t x, int16_t y, uint16_t color);
  439. void drawPixels(uint16_t p[], uint16_t count, int16_t x, int16_t y);
  440. uint16_t getPixel(int16_t x, int16_t y);
  441. //void getPixels(uint16_t * p, uint32_t count, int16_t x, int16_t y);
  442. void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
  443. void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
  444. void fillWindow(uint16_t color=_RA8875_DEFAULTBACKLIGHT);//fill the ActiveWindow with a color(default black)
  445. void clearScreen(uint16_t color=_RA8875_DEFAULTBACKLIGHT);//fill the entire screen (regardless ActiveWindow) with a color(default black)
  446. void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
  447. void drawLineAngle(int16_t x, int16_t y, int16_t angle, uint16_t length, uint16_t color,int offset = -90);
  448. void drawLineAngle(int16_t x, int16_t y, int16_t angle, uint16_t start, uint16_t length, uint16_t color,int offset = -90);
  449. void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
  450. void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
  451. void writeRect(int16_t x, int16_t y, int16_t w, int16_t h, const uint16_t *pcolors);
  452. void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
  453. void fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
  454. void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
  455. void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
  456. void drawEllipse(int16_t xCenter, int16_t yCenter, int16_t longAxis, int16_t shortAxis, uint16_t color);
  457. void fillEllipse(int16_t xCenter, int16_t yCenter, int16_t longAxis, int16_t shortAxis, uint16_t color);
  458. void drawCurve(int16_t xCenter, int16_t yCenter, int16_t longAxis, int16_t shortAxis, uint8_t curvePart, uint16_t color);
  459. void fillCurve(int16_t xCenter, int16_t yCenter, int16_t longAxis, int16_t shortAxis, uint8_t curvePart, uint16_t color);
  460. void drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color);//ok
  461. void fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color);
  462. void drawQuad(int16_t x0, int16_t y0,int16_t x1, int16_t y1,int16_t x2, int16_t y2,int16_t x3, int16_t y3, uint16_t color);
  463. void fillQuad(int16_t x0, int16_t y0,int16_t x1, int16_t y1,int16_t x2, int16_t y2, int16_t x3, int16_t y3, uint16_t color, bool triangled=true);
  464. void drawPolygon(int16_t cx, int16_t cy, uint8_t sides, int16_t diameter, float rot, uint16_t color);
  465. void drawMesh(int16_t x, int16_t y, int16_t w, int16_t h, uint8_t spacing,uint16_t color);
  466. void setArcParams(float arcAngleMax, int arcAngleOffset);
  467. void setAngleOffset(int16_t angleOffset);
  468. inline __attribute__((always_inline)) void drawArc(uint16_t cx, uint16_t cy, uint16_t radius, uint16_t thickness, float start, float end, uint16_t color) {
  469. if (start == 0 && end == _arcAngle_max) {
  470. _drawArc_helper(cx, cy, radius, thickness, 0, _arcAngle_max, color);
  471. } else {
  472. _drawArc_helper(cx, cy, radius, thickness, start + (_arcAngle_offset / (float)360)*_arcAngle_max, end + (_arcAngle_offset / (float)360)*_arcAngle_max, color);
  473. }
  474. }
  475. //-------------- GAUGES ---------------------------------------------------------------------------
  476. void ringMeter(int val, int minV, int maxV, int16_t x, int16_t y, uint16_t r, const char* units="none", uint16_t colorScheme=4,uint16_t backSegColor=RA8875_BLACK,int16_t angle=150,uint8_t inc=10);
  477. void roundGaugeTicker(uint16_t x, uint16_t y, uint16_t r, int from, int to, float dev,uint16_t color);
  478. //-------------- LAYERS --------------------------------------------------------------------------
  479. void useLayers(boolean on);//mainly used to turn of layers!
  480. void writeTo(enum RA8875writes d);//L1, L2, CGRAM, PATTERN, CURSOR
  481. void layerEffect(enum RA8875boolean efx);//LAYER1, LAYER2, TRANSPARENT, LIGHTEN, OR, AND, FLOATING
  482. void layerTransparency(uint8_t layer1,uint8_t layer2);
  483. uint8_t getCurrentLayer(void); //return the current drawing layer. If layers are OFF, return 255
  484. //--------------- SCROLL --------------------------------------------------------------------------
  485. void setScrollMode(enum RA8875scrollMode mode); // The experimentalist
  486. void setScrollWindow(int16_t XL,int16_t XR ,int16_t YT ,int16_t YB);
  487. void scroll(int16_t x,int16_t y);
  488. //-------------- DMA ------------------------------------------------------------------------------
  489. void DMA_blockModeSize(int16_t BWR,int16_t BHR,int16_t SPWR);
  490. void DMA_startAddress(unsigned long adrs);
  491. void DMA_enable(void);
  492. void drawFlashImage(int16_t x,int16_t y,int16_t w,int16_t h,uint8_t picnum);
  493. //-------------- BTE -------------------------------------------------------------------------------
  494. void BTE_size(int16_t w, int16_t h);
  495. void BTE_moveFrom(int16_t SX,int16_t SY);
  496. void BTE_moveTo(int16_t DX,int16_t DY);
  497. //void BTE_source_destination(uint16_t SX,uint16_t DX ,uint16_t SY ,uint16_t DY);
  498. void BTE_ropcode(unsigned char setx);//
  499. void BTE_enable(bool on);//
  500. void BTE_dataMode(enum RA8875btedatam m);//CONT,RECT
  501. void BTE_layer(enum RA8875btelayer sd,uint8_t l);//SOURCE,DEST - 1 or 2
  502. void BTE_move(int16_t SourceX, int16_t SourceY, int16_t Width, int16_t Height, int16_t DestX, int16_t DestY, uint8_t SourceLayer=0, uint8_t DestLayer=0, bool Transparent = false, uint8_t ROP=RA8875_BTEROP_SOURCE, bool Monochrome=false, bool ReverseDir = false);
  503. //---------- PATTERN --------------------------------------------------------------------------
  504. void setPattern(uint8_t num, enum RA8875pattern p=P8X8);
  505. void writePattern(int16_t x,int16_t y,const uint8_t *data,uint8_t size,bool setAW=true);
  506. //-------------- GPIO & PWM -------------------------
  507. void GPIOX(boolean on);
  508. void PWMout(uint8_t pw,uint8_t p);//1:backlight, 2:free
  509. //-------------- ISR ------------------------------------------------------------------------------
  510. void useINT(const uint8_t INTpin=2,const uint8_t INTnum=0);
  511. void enableISR(bool force = false);
  512. void setInternalInt(enum RA8875intlist b);// BTE,TOUCH,DMA,KEY
  513. void clearInternalInt(enum RA8875intlist b);// BTE,TOUCH,DMA,KEY
  514. //-------------- TOUCH SCREEN ---------------------------------------------------------------------
  515. #if !defined(_AVOID_TOUCHSCREEN)
  516. bool touched(bool safe=false);
  517. void setTouchLimit(uint8_t limit);//5 for FT5206, 1 for RA8875
  518. uint8_t getTouchLimit(void);
  519. # if defined(USE_RA8875_TOUCH)
  520. //void useINT(const uint8_t INTpin=2,const uint8_t INTnum=0);
  521. //void enableISR(bool force = false);
  522. void touchBegin(void);//prepare Touch Screen driver
  523. void touchEnable(boolean enabled);//enable/disable Touch Polling (disable INT)
  524. void touchReadAdc(uint16_t *x, uint16_t *y);//returns 10bit ADC data (0...1024)
  525. void touchReadPixel(uint16_t *x, uint16_t *y);//return pixels (0...width, 0...height)
  526. boolean touchCalibrated(void);//true if screen calibration it's present
  527. void setTouchCalibrationData(uint16_t minX, uint16_t maxX, uint16_t minY, uint16_t maxY);
  528. #elif defined (USE_FT5206_TOUCH)
  529. void setWireObject(TwoWire *wire) {_wire = wire; }
  530. void useCapINT(const uint8_t INTpin=2,const uint8_t INTnum=0);
  531. void enableCapISR(bool force = false);
  532. void updateTS(void);
  533. uint8_t getGesture(void);
  534. uint8_t getTouches(void);
  535. uint8_t getTouchState(void);
  536. uint8_t getTScoordinates(uint16_t (*touch_coordinates)[2]);
  537. #endif
  538. #endif
  539. //--------------Text Write -------------------------
  540. //virtual size_t write(uint8_t b) {
  541. // if (_FNTgrandient) _FNTgrandient = false;//cannot use this with write
  542. // _textWrite((const char *)&b, 1);
  543. // return 1;
  544. //}
  545. virtual size_t write(uint8_t c) {
  546. _fontWrite(&c, 1);
  547. return 1;
  548. }
  549. virtual size_t write(const uint8_t *buffer, size_t size){
  550. if(_use_default) {
  551. _textWrite((const char *)buffer, size);
  552. } else {
  553. _fontWrite(buffer, size);
  554. }
  555. return size;
  556. }
  557. using Print::write;
  558. protected:
  559. uint32_t textcolorPrexpanded, textbgcolorPrexpanded;
  560. boolean wrap; // If set, 'wrap' text at right edge of display
  561. const ILI9341_t3_font_t *font;
  562. int16_t _clipx1, _clipy1, _clipx2, _clipy2;
  563. int16_t _originx, _originy;
  564. int16_t _displayclipx1, _displayclipy1, _displayclipx2, _displayclipy2;
  565. // GFX Font support
  566. const GFXfont *gfxFont = nullptr;
  567. int8_t _gfxFont_min_yOffset = 0;
  568. // Opaque font chracter overlap?
  569. unsigned int _gfx_c_last;
  570. int16_t _gfx_last__cursorX, _gfx_last__cursorY;
  571. int16_t _gfx_last_char_x_write = 0;
  572. uint16_t _gfx_last_char_textcolor;
  573. uint16_t _gfx_last_char_textbgcolor;
  574. bool gfxFontLastCharPosFG(int16_t x, int16_t y);
  575. //=====================
  576. volatile bool _textMode;
  577. volatile uint8_t _MWCR0_Reg; //keep track of the register [0x40]
  578. int16_t RA8875_WIDTH, RA8875_HEIGHT;//absolute
  579. int16_t _width, _height;
  580. int16_t _cursorX, _cursorY;
  581. uint8_t _scaleX, _scaleY;
  582. bool _scaling;
  583. uint8_t _FNTwidth, _FNTheight;
  584. uint8_t _FNTbaselineLow, _FNTbaselineTop;
  585. volatile uint8_t _TXTparameters;
  586. /* It contains several parameters in one byte
  587. bit parameter
  588. 0 -> _extFontRom i's using an ext rom font
  589. 1 -> _autoAdvance after a char the pointer move ahead
  590. 2 -> _textWrap
  591. 3 -> _fontFullAlig
  592. 4 -> _fontRotation (actually not used)
  593. 5 -> _alignXToCenter;
  594. 6 -> _alignYToCenter;
  595. 7 -> _renderFont active;
  596. */
  597. bool _FNTgrandient;
  598. uint16_t _FNTgrandientColor1;
  599. uint16_t _FNTgrandientColor2;
  600. bool _FNTcompression;
  601. int _spaceCharWidth;
  602. volatile bool _needISRrearm;
  603. volatile uint8_t _enabledInterrups;
  604. // Allow up to three displays to have touch?
  605. static void _isr(void);
  606. static void _isr1(void);
  607. static void _isr2(void);
  608. static RA8875 *_active_touch_objects[3];
  609. volatile uint8_t _RA8875_INTS = 0b00000000;//container for INT states
  610. #if !defined(_AVOID_TOUCHSCREEN)
  611. volatile bool _touchEnabled;
  612. volatile bool _clearTInt;
  613. #endif
  614. #if defined(USE_FT5206_TOUCH)
  615. volatile bool _needCTS_ISRrearm;
  616. static void cts_isr(void);
  617. #if defined(___DUESTUFF) && defined(USE_DUE_WIRE1_INTERFACE)
  618. TwoWire *_wire=&Wire1;
  619. #else
  620. TwoWire *_wire=&Wire;
  621. #endif
  622. #elif defined(USE_RA8875_TOUCH)
  623. //volatile bool _touchEnabled;
  624. //volatile bool _clearTInt;
  625. #endif
  626. #ifdef SPI_HAS_TRANSACTION
  627. volatile uint32_t _SPITransactionSpeed; //holder for SPI speed
  628. uint32_t _SPIMaxSpeed; // Max Speed defined in either begin or presets...
  629. uint32_t _SPIMaxReadSpeed; // Max Read speed defined in either begin or presets.
  630. #endif
  631. #if defined(TEENSYDUINO)//all of them (32 bit only)
  632. uint8_t _cs;
  633. uint8_t _miso, _mosi, _sclk;
  634. #if defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__) || defined(__MKL26Z64__)
  635. SPIClass *_pspi; // which SPI are we using...
  636. #endif
  637. #elif defined(ENERGIA)
  638. uint8_t _cs;
  639. #else
  640. #if defined(___DUESTUFF)
  641. #if defined(_FASTSSPORT)
  642. uint32_t _cs, cspinmask;
  643. #else
  644. uint8_t _cs;
  645. #endif
  646. #elif defined(ESP8266)
  647. #if defined(_FASTSSPORT)
  648. uint32_t _cs;
  649. #else
  650. uint8_t _cs;
  651. #endif
  652. #elif defined(SPARK)
  653. #if defined(_FASTSSPORT)
  654. uint32_t _cs;
  655. #else
  656. uint8_t _cs;
  657. #endif
  658. #else
  659. #if defined(_FASTSSPORT)
  660. uint8_t _cs, cspinmask;
  661. #else
  662. uint8_t _cs;
  663. #endif
  664. #endif
  665. #endif
  666. private:
  667. //HACK
  668. uint8_t _use_ili_font = 0;
  669. uint8_t _use_gfx_font = 0;
  670. uint8_t _use_tfont = 0;
  671. uint8_t _use_int_font = 0;
  672. uint8_t _use_default = 1;
  673. uint8_t textsize, textsize_x, textsize_y;
  674. uint16_t textcolor, textbgcolor;
  675. //anti-alias font
  676. uint8_t fontbpp = 1;
  677. uint8_t fontbppindex = 0;
  678. uint8_t fontbppmask = 1;
  679. uint8_t fontppb = 8;
  680. uint8_t* fontalphalut;
  681. float fontalphamx = 1;
  682. uint8_t _rst;
  683. uint8_t _intPin;
  684. uint8_t _intNum;
  685. bool _useISR;
  686. const tFont * _currentFont;
  687. bool _checkInterrupt(uint8_t _bit,bool _clear=true);
  688. void _disableISR(void);
  689. uint32_t fetchbit(const uint8_t *p, uint32_t index);
  690. uint32_t fetchbits_unsigned(const uint8_t *p, uint32_t index, uint32_t required);
  691. uint32_t fetchbits_signed(const uint8_t *p, uint32_t index, uint32_t required);
  692. void _fontWrite(const uint8_t* buffer, uint16_t len);
  693. /**
  694. * Found in a pull request for the Adafruit framebuffer library. Clever!
  695. * https://github.com/tricorderproject/arducordermini/pull/1/files#diff-d22a481ade4dbb4e41acc4d7c77f683d
  696. * Converts 0000000000000000rrrrrggggggbbbbb
  697. * into 00000gggggg00000rrrrr000000bbbbb
  698. * with mask 00000111111000001111100000011111
  699. * This is useful because it makes space for a parallel fixed-point multiply
  700. * This implements the linear interpolation formula: result = bg * (1.0 - alpha) + fg * alpha
  701. * This can be factorized into: result = bg + (fg - bg) * alpha
  702. * alpha is in Q1.5 format, so 0.0 is represented by 0, and 1.0 is represented by 32
  703. * @param fg Color to draw in RGB565 (16bit)
  704. * @param bg Color to draw over in RGB565 (16bit)
  705. * @param alpha Alpha in range 0-255
  706. **/
  707. uint16_t alphaBlendRGB565( uint32_t fg, uint32_t bg, uint8_t alpha )
  708. __attribute__((always_inline)) {
  709. alpha = ( alpha + 4 ) >> 3; // from 0-255 to 0-31
  710. bg = (bg | (bg << 16)) & 0b00000111111000001111100000011111;
  711. fg = (fg | (fg << 16)) & 0b00000111111000001111100000011111;
  712. uint32_t result = ((((fg - bg) * alpha) >> 5) + bg) & 0b00000111111000001111100000011111;
  713. return (uint16_t)((result >> 16) | result); // contract result
  714. }
  715. /**
  716. * Same as above, but fg and bg are premultiplied, and alpah is already in range 0-31
  717. */
  718. uint16_t alphaBlendRGB565Premultiplied( uint32_t fg, uint32_t bg, uint8_t alpha )
  719. __attribute__((always_inline)) {
  720. uint32_t result = ((((fg - bg) * alpha) >> 5) + bg) & 0b00000111111000001111100000011111;
  721. return (uint16_t)((result >> 16) | result); // contract result
  722. }
  723. uint32_t fetchpixel(const uint8_t *p, uint32_t index, uint32_t x);
  724. // Touch Screen vars ---------------------
  725. #if !defined(_AVOID_TOUCHSCREEN)
  726. uint8_t _maxTouch;//5 on FT5206, 1 on resistive
  727. #if defined(USE_FT5206_TOUCH)// FT5206 specifics
  728. uint8_t _intCTSNum;
  729. uint8_t _intCTSPin;
  730. uint8_t _cptRegisters[31];
  731. uint8_t _gesture;
  732. uint8_t _currentTouches;//0...5
  733. uint8_t _currentTouchState;//0,1,2
  734. void _initializeFT5206(void);
  735. void _sendRegFT5206(uint8_t reg,const uint8_t val);
  736. void _disableCapISR(void);
  737. #elif defined(USE_RA8875_TOUCH)//RA8875 internal resistive specifics
  738. uint16_t _tsAdcMinX,_tsAdcMinY,_tsAdcMaxX,_tsAdcMaxY;
  739. uint16_t _touchrcal_xlow,_touchrcal_ylow,_touchrcal_xhigh,_touchrcal_yhigh;
  740. void readTouchADC(uint16_t *x, uint16_t *y);
  741. bool _calibrated;
  742. boolean _isCalibrated(void);//true if screen calibration it's present
  743. #endif
  744. #endif
  745. #if defined(USE_RA8875_KEYMATRIX)
  746. bool _keyMatrixEnabled;
  747. #endif
  748. //system vars -------------------------------------------
  749. bool _inited;//true when init has been ended
  750. bool _sleep;
  751. enum RA8875sizes _displaySize;//Adafruit_480x272, etc
  752. bool _portrait;
  753. uint8_t _rotation;
  754. uint8_t _initIndex;
  755. int16_t _activeWindowXL,_activeWindowXR,_activeWindowYT,_activeWindowYB;
  756. uint8_t _errorCode;
  757. //color vars ----------------------------------------------
  758. uint16_t _foreColor;
  759. uint16_t _backColor;
  760. bool _backTransparent;
  761. uint8_t _colorIndex;
  762. #if defined(USE_RA8875_SEPARATE_TEXT_COLOR)
  763. uint16_t _TXTForeColor;
  764. uint16_t _TXTBackColor;
  765. bool _TXTrecoverColor;
  766. #endif
  767. //text vars-------------------------------------------------
  768. uint8_t _FNTspacing;
  769. uint8_t _FNTinterline;
  770. enum RA8875extRomFamily _EXTFNTfamily;
  771. enum RA8875extRomType _EXTFNTrom;
  772. enum RA8875extRomCoding _EXTFNTcoding;
  773. enum RA8875tsize _EXTFNTsize;//X16,X24,X32
  774. enum RA8875fontSource _FNTsource;
  775. enum RA8875tcursor _FNTcursorType;
  776. //centering -------------------------------
  777. bool _relativeCenter;
  778. bool _absoluteCenter;
  779. //layer vars -----------------------------
  780. uint8_t _maxLayers;
  781. bool _useMultiLayers;
  782. uint8_t _currentLayer;
  783. bool _hasLayerLimits;//helper
  784. //scroll vars ----------------------------
  785. int16_t _scrollXL,_scrollXR,_scrollYT,_scrollYB;
  786. //color space-----------------------------
  787. uint8_t _color_bpp;//8=256, 16=64K colors
  788. uint8_t _brightness;
  789. //various
  790. float _arcAngle_max;
  791. int _arcAngle_offset;
  792. int _angle_offset;
  793. // Register containers -----------------------------------------
  794. // this needed to prevent readRegister from chip that it's slow.
  795. uint8_t _DPCR_Reg; ////Display Configuration [0x20]
  796. uint8_t _FNCR0_Reg; //Font Control Register 0 [0x21]
  797. uint8_t _FNCR1_Reg; //Font Control Register1 [0x22]
  798. uint8_t _FWTSET_Reg; //Font Write Type Setting Register [0x2E]
  799. uint8_t _SFRSET_Reg; //Serial Font ROM Setting [0x2F]
  800. uint8_t _INTC1_Reg; //Interrupt Control Register1 [0xF0]
  801. // functions --------------------------------------------------
  802. void _initialize();
  803. void _setSysClock(uint8_t pll1,uint8_t pll2,uint8_t pixclk);
  804. // TEXT writing stuff-------------------------------------------
  805. void _textWrite(const char* buffer, uint16_t len=0);//thanks to Paul Stoffregen for the initial version of this one
  806. void _charWrite(const char c,uint8_t offset);
  807. void _charWriteR(const char c,uint8_t offset,uint16_t fcolor,uint16_t bcolor);
  808. int _getCharCode(uint8_t ch);
  809. #if defined(_RA8875_TXTRNDOPTIMIZER)
  810. void _drawChar_unc(int16_t x,int16_t y,int charW,int index,uint16_t fcolor);
  811. #else
  812. void _drawChar_unc(int16_t x,int16_t y,int16_t w,const uint8_t *data,uint16_t fcolor,uint16_t bcolor);
  813. #endif
  814. //void _drawChar_com(int16_t x,int16_t y,int16_t w,const uint8_t *data);
  815. void _textPosition(int16_t x, int16_t y,bool update);
  816. void _setFNTdimensions(uint8_t index);
  817. int16_t _STRlen_helper(const char* buffer,uint16_t len=0);
  818. void fontRomSpeed(uint8_t sp);
  819. //--------------------------------------------------------------------
  820. void PWMsetup(uint8_t pw,boolean on, uint8_t clock);
  821. void _updateActiveWindow(bool full);
  822. void _setTextMode(bool m);
  823. void _scanDirection(boolean invertH,boolean invertV);
  824. // helpers-----------------------------
  825. void _circle_helper(int16_t x0, int16_t y0, int16_t r, uint16_t color, bool filled);
  826. void _rect_helper(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color, bool filled);
  827. void _roundRect_helper(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color, bool filled);
  828. float _check_area(int16_t Ax, int16_t Ay, int16_t Bx, int16_t By, int16_t Cx, int16_t Cy);
  829. void _triangle_helper(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color, bool filled);
  830. void _ellipseCurve_helper(int16_t xCenter, int16_t yCenter, int16_t longAxis, int16_t shortAxis,uint8_t curvePart, uint16_t color, bool filled);
  831. void _drawArc_helper(uint16_t cx, uint16_t cy, uint16_t radius, uint16_t thickness, float startAngle, float endAngle, uint16_t color);
  832. void _line_addressing(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
  833. void _curve_addressing(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
  834. float _cosDeg_helper(float angle);
  835. float _sinDeg_helper(float angle);
  836. #if defined(_RA8875_TXTRNDOPTIMIZER)
  837. void _charLineRender(bool lineBuffer[],int charW,int16_t x,int16_t y,int16_t currentYposition,uint16_t fcolor);
  838. #endif
  839. //convert a 16bit color(565) into 8bit color(332) as requested by RA8875 datasheet
  840. //inline __attribute__((always_inline))
  841. uint8_t _color16To8bpp(uint16_t color)
  842. __attribute__((always_inline)) {
  843. return ((color & 0xe000) >> 8) | ((color & 0x700) >> 6) | ((color & 0x18) >> 3);
  844. // return (map((color & 0xF800) >> 11, 0,28, 0,7)<<5 | map((color & 0x07E0) >> 5, 0,56, 0,7)<<2 | map(color & 0x001F, 0,24, 0,3));
  845. }
  846. //inline __attribute__((always_inline))
  847. void _checkLimits_helper(int16_t &x,int16_t &y)
  848. __attribute__((always_inline)) {
  849. if (x < 0) x = 0;
  850. if (y < 0) y = 0;
  851. if (x >= RA8875_WIDTH) x = RA8875_WIDTH - 1;
  852. if (y >= RA8875_HEIGHT) y = RA8875_HEIGHT -1;
  853. x = x;
  854. y = y;
  855. }
  856. //inline __attribute__((always_inline))
  857. void _center_helper(int16_t &x, int16_t &y)
  858. __attribute__((always_inline)) {
  859. if (x == CENTER) x = _width/2;
  860. if (y == CENTER) y = _height/2;
  861. }
  862. #if defined(TEENSYDUINO)//all of them (32 bit only)
  863. // nothing, already done
  864. #elif defined(ENERGIA)
  865. // TODO
  866. #else
  867. #if defined(___DUESTUFF) // DUE
  868. #if defined(_FASTSSPORT)
  869. volatile uint32_t *csport;
  870. #endif
  871. #elif defined(ESP8266) // ESP8266
  872. uint32_t _pinRegister(uint8_t pin)
  873. __attribute__((always_inline)) {
  874. return _BV(pin);
  875. }
  876. #elif defined(SPARK)
  877. // Mmmm, dunno... put nothing for now
  878. #else// AVR,ARM (not DUE),STM,CHIPKIT
  879. //TODO:must check if all processor are compatible
  880. #if defined(_FASTSSPORT)
  881. volatile uint8_t *csport;
  882. #endif
  883. #endif
  884. #endif
  885. // Low level access commands ----------------------
  886. //inline __attribute__((always_inline))
  887. void _startSend()
  888. __attribute__((always_inline)) {
  889. #if defined(SPI_HAS_TRANSACTION)
  890. #if defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__) || defined(__MKL26Z64__)
  891. _pspi->beginTransaction(SPISettings(_SPITransactionSpeed, MSBFIRST, SPI_MODE3));
  892. #elif defined(ESP8266)
  893. SPI.beginTransaction(SPISettings(_SPITransactionSpeed, MSBFIRST, SPI_MODE3));//it works, anyway ESP doesn't work in MODE3!
  894. #elif defined(SPARK)
  895. SPI.beginTransaction(SPISettings(_SPITransactionSpeed, MSBFIRST, SPI_MODE0));//TODO !
  896. #else
  897. SPI.beginTransaction(SPISettings(_SPITransactionSpeed, MSBFIRST, SPI_MODE3));
  898. #endif
  899. #elif !defined(ENERGIA) && !defined(_SPITransactionSpeed) && !defined(___STM32STUFF) && !defined(ESP8266) && !defined(SPARK)
  900. cli();//protect from interrupts
  901. #endif//end has transaction
  902. #if defined(TEENSYDUINO)//all of them (32 bit only)
  903. digitalWriteFast(_cs, LOW);
  904. #elif !defined(ENERGIA)//UNO,DUE,ETC.
  905. #if defined(___DUESTUFF) && defined(SPI_DUE_MODE_EXTENDED)//DUE extended SPI
  906. //nothing
  907. #else//DUE (normal),UNO,ETC.
  908. #if defined(ESP8266)
  909. #if defined(_FASTSSPORT)
  910. GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, _pinRegister(_cs));//L
  911. #else
  912. digitalWrite(_cs, LOW);// for now
  913. #endif
  914. #elif defined(SPARK)
  915. pinResetFast(_cs);
  916. #elif !defined(ESP8266) && defined(_FASTSSPORT)
  917. *csport &= ~cspinmask;
  918. #else
  919. digitalWrite(_cs, LOW);
  920. #endif
  921. #endif
  922. #else//ENERGIA
  923. digitalWrite(_cs, LOW);
  924. #endif
  925. }
  926. //inline __attribute__((always_inline))
  927. void _endSend()
  928. __attribute__((always_inline)) {
  929. #if defined(TEENSYDUINO)//all of them (32 bit only)
  930. digitalWriteFast(_cs, HIGH);
  931. #elif !defined(ENERGIA)
  932. #if defined(___DUESTUFF) && defined(SPI_DUE_MODE_EXTENDED)//DUE extended SPI
  933. //nothing
  934. #else//DUE (normal),UNO,ETC.
  935. #if defined(ESP8266)
  936. #if defined(_FASTSSPORT)
  937. GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, _pinRegister(_cs));//H
  938. #else
  939. digitalWrite(_cs, HIGH);
  940. #endif
  941. #elif defined(SPARK)
  942. pinSetFast(_cs);
  943. #elif !defined(ESP8266) && defined(_FASTSSPORT)
  944. *csport |= cspinmask;
  945. #else
  946. digitalWrite(_cs, HIGH);
  947. #endif
  948. #endif
  949. #else//ENERGIA
  950. digitalWrite(_cs, HIGH);
  951. #endif
  952. #if defined(SPI_HAS_TRANSACTION)
  953. #if defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__) || defined(__MKL26Z64__)
  954. _pspi->endTransaction();
  955. #else
  956. SPI.endTransaction();
  957. #endif
  958. #elif !defined(ENERGIA) && !defined(SPI_HAS_TRANSACTION) && !defined(___STM32STUFF) && !defined(ESP8266) && !defined(SPARK)
  959. sei();//enable interrupts
  960. #endif
  961. }
  962. void _writeRegister(const uint8_t reg, uint8_t val);
  963. uint8_t _readRegister(const uint8_t reg);
  964. void _writeData(uint8_t data);
  965. uint8_t _readData(bool stat=false);
  966. boolean _waitPoll(uint8_t r, uint8_t f, uint8_t timeout=15);//from adafruit add settable timeout
  967. void _waitBusy(uint8_t res=0x80);//0x80, 0x40(BTE busy), 0x01(DMA busy)
  968. #if defined(NEEDS_SET_MODULE)//for Energia
  969. void selectCS(uint8_t module);
  970. #endif
  971. #if defined(_FASTCPU)
  972. //inline __attribute__((always_inline))
  973. void _slowDownSPI(bool slow,uint32_t slowSpeed=10000000UL)
  974. __attribute__((always_inline)) {
  975. #if defined(SPI_HAS_TRANSACTION)
  976. if (slow){
  977. _SPITransactionSpeed = slowSpeed;
  978. } else {
  979. _SPITransactionSpeed = _SPIMaxSpeed;
  980. }
  981. #else
  982. if (slow){
  983. #if defined(___DUESTUFF) && defined(SPI_DUE_MODE_EXTENDED)
  984. SPI.setClockDivider(_cs,SPI_SPEED_SAFE);
  985. #else
  986. SPI.setClockDivider(SPI_SPEED_SAFE);
  987. #endif
  988. } else {
  989. #if defined(___DUESTUFF) && defined(SPI_DUE_MODE_EXTENDED)
  990. SPI.setClockDivider(_cs,SPI_SPEED_WRITE);
  991. #else
  992. SPI.setClockDivider(SPI_SPEED_WRITE);
  993. #endif
  994. }
  995. #endif
  996. }
  997. #endif
  998. #if defined(__AVR__)
  999. //inline __attribute__((always_inline))
  1000. void _spiwrite16(uint16_t d)
  1001. __attribute__((always_inline)) {
  1002. SPDR = highByte(d);
  1003. while (!(SPSR & _BV(SPIF)));
  1004. SPDR = lowByte(d);
  1005. while (!(SPSR & _BV(SPIF)));
  1006. }
  1007. //inline __attribute__((always_inline))
  1008. void _spiwrite(uint8_t c)
  1009. __attribute__((always_inline)) {
  1010. SPDR = c;
  1011. //asm volatile("nop");
  1012. while (!(SPSR & _BV(SPIF)));
  1013. }
  1014. //inline __attribute__((always_inline))
  1015. uint8_t _spiread(void)
  1016. __attribute__((always_inline)) {
  1017. uint8_t r = 0;
  1018. SPDR = 0x00;
  1019. //asm volatile("nop");
  1020. while(!(SPSR & _BV(SPIF)));
  1021. r = SPDR;
  1022. return r;
  1023. }
  1024. #elif defined(SPARK)
  1025. void _spiwrite16(uint16_t d)
  1026. __attribute__((always_inline)) {
  1027. SPI.transfer(d >> 8);
  1028. SPI.transfer(d & 0xFF);
  1029. }
  1030. void _spiwrite(uint8_t c)
  1031. __attribute__((always_inline)) {
  1032. SPI.transfer(c);
  1033. }
  1034. uint8_t _spiread(void)
  1035. __attribute__((always_inline)) {
  1036. uint8_t r = SPI.transfer(0x00);
  1037. return r;
  1038. }
  1039. #endif
  1040. };
  1041. #endif // __cplusplus
  1042. #endif