My Marlin configs for Fabrikator Mini and CTC i3 Pro B
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.

u8g_dev_tft_320x240_upscale_from_128x64.cpp 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /*
  23. u8g_dev_tft_320x240_upscale_from_128x64.cpp
  24. Universal 8bit Graphics Library
  25. Copyright (c) 2011, olikraus@gmail.com
  26. All rights reserved.
  27. Redistribution and use in source and binary forms, with or without modification,
  28. are permitted provided that the following conditions are met:
  29. * Redistributions of source code must retain the above copyright notice, this list
  30. of conditions and the following disclaimer.
  31. * Redistributions in binary form must reproduce the above copyright notice, this
  32. list of conditions and the following disclaimer in the documentation and/or other
  33. materials provided with the distribution.
  34. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  35. CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  36. INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  37. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  39. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41. NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  43. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44. STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  46. ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47. */
  48. #include "../../inc/MarlinConfig.h"
  49. #if HAS_GRAPHICAL_LCD && PIN_EXISTS(FSMC_CS)
  50. #include "HAL_LCD_com_defines.h"
  51. #include "ultralcd_DOGM.h"
  52. #include <string.h>
  53. #if ENABLED(LCD_USE_DMA_FSMC)
  54. extern void LCD_IO_WriteReg(uint16_t Reg);
  55. extern void LCD_IO_WriteData(uint16_t RegValue);
  56. extern void LCD_IO_WriteSequence(uint16_t *data, uint16_t length);
  57. extern void LCD_IO_WriteSequence_Async(uint16_t *data, uint16_t length);
  58. extern void LCD_IO_WaitSequence_Async();
  59. extern void LCD_IO_WriteMultiple(uint16_t color, uint32_t count);
  60. #endif
  61. #define WIDTH LCD_PIXEL_WIDTH
  62. #define HEIGHT LCD_PIXEL_HEIGHT
  63. #define PAGE_HEIGHT 8
  64. #define X_LO LCD_PIXEL_OFFSET_X
  65. #define Y_LO LCD_PIXEL_OFFSET_Y
  66. #define X_HI (X_LO + 2 * WIDTH - 1)
  67. #define Y_HI (Y_LO + 2 * HEIGHT - 1)
  68. // see https://ee-programming-notepad.blogspot.com/2016/10/16-bit-color-generator-picker.html
  69. #define COLOR_BLACK 0x0000 // #000000
  70. #define COLOR_WHITE 0xFFFF // #FFFFFF
  71. #define COLOR_SILVER 0xC618 // #C0C0C0
  72. #define COLOR_GREY 0x7BEF // #808080
  73. #define COLOR_DARKGREY 0x4208 // #404040
  74. #define COLOR_DARKGREY2 0x39E7 // #303030
  75. #define COLOR_DARK 0x0003 // Some dark color
  76. #define COLOR_RED 0xF800 // #FF0000
  77. #define COLOR_LIME 0x7E00 // #00FF00
  78. #define COLOR_BLUE 0x001F // #0000FF
  79. #define COLOR_YELLOW 0xFFE0 // #FFFF00
  80. #define COLOR_MAGENTA 0xF81F // #FF00FF
  81. #define COLOR_FUCHSIA 0xF81F // #FF00FF
  82. #define COLOR_CYAN 0x07FF // #00FFFF
  83. #define COLOR_AQUA 0x07FF // #00FFFF
  84. #define COLOR_MAROON 0x7800 // #800000
  85. #define COLOR_GREEN 0x03E0 // #008000
  86. #define COLOR_NAVY 0x000F // #000080
  87. #define COLOR_OLIVE 0x8400 // #808000
  88. #define COLOR_PURPLE 0x8010 // #800080
  89. #define COLOR_TEAL 0x0410 // #008080
  90. #define COLOR_ORANGE 0xFC00 // #FF7F00
  91. #ifndef TFT_MARLINUI_COLOR
  92. #define TFT_MARLINUI_COLOR COLOR_WHITE
  93. #endif
  94. #ifndef TFT_MARLINBG_COLOR
  95. #define TFT_MARLINBG_COLOR COLOR_BLACK
  96. #endif
  97. #ifndef TFT_DISABLED_COLOR
  98. #define TFT_DISABLED_COLOR COLOR_DARK
  99. #endif
  100. #ifndef TFT_BTCANCEL_COLOR
  101. #define TFT_BTCANCEL_COLOR COLOR_RED
  102. #endif
  103. #ifndef TFT_BTARROWS_COLOR
  104. #define TFT_BTARROWS_COLOR COLOR_BLUE
  105. #endif
  106. #ifndef TFT_BTOKMENU_COLOR
  107. #define TFT_BTOKMENU_COLOR COLOR_RED
  108. #endif
  109. static uint32_t lcd_id = 0;
  110. #define ST7789V_CASET 0x2A /* Column address register */
  111. #define ST7789V_RASET 0x2B /* Row address register */
  112. #define ST7789V_WRITE_RAM 0x2C /* Write data to GRAM */
  113. /* Mind the mess: with landscape screen orientation 'Horizontal' is Y and 'Vertical' is X */
  114. #define ILI9328_HASET 0x20 /* Horizontal GRAM address register (0-255) */
  115. #define ILI9328_VASET 0x21 /* Vertical GRAM address register (0-511)*/
  116. #define ILI9328_WRITE_RAM 0x22 /* Write data to GRAM */
  117. #define ILI9328_HASTART 0x50 /* Horizontal address start position (0-255) */
  118. #define ILI9328_HAEND 0x51 /* Horizontal address end position (0-255) */
  119. #define ILI9328_VASTART 0x52 /* Vertical address start position (0-511) */
  120. #define ILI9328_VAEND 0x53 /* Vertical address end position (0-511) */
  121. static void setWindow_ili9328(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {
  122. #ifdef LCD_USE_DMA_FSMC
  123. LCD_IO_WriteReg(ILI9328_HASTART);
  124. LCD_IO_WriteData(Ymin);
  125. LCD_IO_WriteReg(ILI9328_HAEND);
  126. LCD_IO_WriteData(Ymax);
  127. LCD_IO_WriteReg(ILI9328_VASTART);
  128. LCD_IO_WriteData(Xmin);
  129. LCD_IO_WriteReg(ILI9328_VAEND);
  130. LCD_IO_WriteData(Xmax);
  131. LCD_IO_WriteReg(ILI9328_HASET);
  132. LCD_IO_WriteData(Ymin);
  133. LCD_IO_WriteReg(ILI9328_VASET);
  134. LCD_IO_WriteData(Xmin);
  135. LCD_IO_WriteReg(ILI9328_WRITE_RAM);
  136. #else
  137. u8g_SetAddress(u8g, dev, 0);
  138. u8g_WriteByte(u8g, dev, ILI9328_HASTART);
  139. u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymin);
  140. u8g_WriteByte(u8g, dev, ILI9328_HAEND);
  141. u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymax);
  142. u8g_WriteByte(u8g, dev, ILI9328_VASTART);
  143. u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmin);
  144. u8g_WriteByte(u8g, dev, ILI9328_VAEND);
  145. u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmax);
  146. u8g_WriteByte(u8g, dev, ILI9328_HASET);
  147. u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Ymin);
  148. u8g_WriteByte(u8g, dev, ILI9328_VASET);
  149. u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&Xmin);
  150. u8g_WriteByte(u8g, dev, ILI9328_WRITE_RAM);
  151. u8g_SetAddress(u8g, dev, 1);
  152. #endif
  153. }
  154. static void setWindow_st7789v(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {
  155. #ifdef LCD_USE_DMA_FSMC
  156. LCD_IO_WriteReg(ST7789V_CASET);
  157. LCD_IO_WriteData((Xmin >> 8) & 0xFF);
  158. LCD_IO_WriteData(Xmin & 0xFF);
  159. LCD_IO_WriteData((Xmax >> 8) & 0xFF);
  160. LCD_IO_WriteData(Xmax & 0xFF);
  161. LCD_IO_WriteReg(ST7789V_RASET);
  162. LCD_IO_WriteData((Ymin >> 8) & 0xFF);
  163. LCD_IO_WriteData(Ymin & 0xFF);
  164. LCD_IO_WriteData((Ymax >> 8) & 0xFF);
  165. LCD_IO_WriteData(Ymax & 0xFF);
  166. LCD_IO_WriteReg(ST7789V_WRITE_RAM);
  167. #else
  168. u8g_SetAddress(u8g, dev, 0); u8g_WriteByte(u8g, dev, ST7789V_CASET); u8g_SetAddress(u8g, dev, 1);
  169. u8g_WriteByte(u8g, dev, (Xmin >> 8) & 0xFF);
  170. u8g_WriteByte(u8g, dev, Xmin & 0xFF);
  171. u8g_WriteByte(u8g, dev, (Xmax >> 8) & 0xFF);
  172. u8g_WriteByte(u8g, dev, Xmax & 0xFF);
  173. u8g_SetAddress(u8g, dev, 0); u8g_WriteByte(u8g, dev, ST7789V_RASET); u8g_SetAddress(u8g, dev, 1);
  174. u8g_WriteByte(u8g, dev, (Ymin >> 8) & 0xFF);
  175. u8g_WriteByte(u8g, dev, Ymin & 0xFF);
  176. u8g_WriteByte(u8g, dev, (Ymax >> 8) & 0xFF);
  177. u8g_WriteByte(u8g, dev, Ymax & 0xFF);
  178. u8g_SetAddress(u8g, dev, 0); u8g_WriteByte(u8g, dev, ST7789V_WRITE_RAM); u8g_SetAddress(u8g, dev, 1);
  179. #endif
  180. }
  181. static void setWindow_none(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) {}
  182. void (*setWindow)(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint16_t Xmax, uint16_t Ymax) = setWindow_none;
  183. #define ESC_REG(x) 0xFFFF, 0x00FF & (uint16_t)x
  184. #define ESC_DELAY(x) 0xFFFF, 0x8000 | (x & 0x7FFF)
  185. #define ESC_END 0xFFFF, 0x7FFF
  186. #define ESC_FFFF 0xFFFF, 0xFFFF
  187. #ifdef LCD_USE_DMA_FSMC
  188. void writeEscSequence(const uint16_t *sequence) {
  189. uint16_t data;
  190. for (;;) {
  191. data = *sequence++;
  192. if (data != 0xFFFF) {
  193. LCD_IO_WriteData(data);
  194. continue;
  195. }
  196. data = *sequence++;
  197. if (data == 0x7FFF) return;
  198. if (data == 0xFFFF) {
  199. LCD_IO_WriteData(data);
  200. } else if (data & 0x8000) {
  201. delay(data & 0x7FFF);
  202. } else if ((data & 0xFF00) == 0) {
  203. LCD_IO_WriteReg(data);
  204. }
  205. }
  206. }
  207. #else
  208. void writeEscSequence8(u8g_t *u8g, u8g_dev_t *dev, const uint16_t *sequence) {
  209. uint16_t data;
  210. u8g_SetAddress(u8g, dev, 1);
  211. for (;;) {
  212. data = *sequence++;
  213. if (data != 0xFFFF) {
  214. u8g_WriteByte(u8g, dev, data & 0xFF);
  215. continue;
  216. }
  217. data = *sequence++;
  218. if (data == 0x7FFF) return;
  219. if (data == 0xFFFF) {
  220. u8g_WriteByte(u8g, dev, data & 0xFF);
  221. } else if (data & 0x8000) {
  222. delay(data & 0x7FFF);
  223. } else if ((data & 0xFF00) == 0) {
  224. u8g_SetAddress(u8g, dev, 0);
  225. u8g_WriteByte(u8g, dev, data & 0xFF);
  226. u8g_SetAddress(u8g, dev, 1);
  227. }
  228. }
  229. }
  230. void writeEscSequence16(u8g_t *u8g, u8g_dev_t *dev, const uint16_t *sequence) {
  231. uint16_t data;
  232. u8g_SetAddress(u8g, dev, 0);
  233. for (;;) {
  234. data = *sequence++;
  235. if (data != 0xFFFF) {
  236. u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&data);
  237. continue;
  238. }
  239. data = *sequence++;
  240. if (data == 0x7FFF) return;
  241. if (data == 0xFFFF) {
  242. u8g_WriteSequence(u8g, dev, 2, (uint8_t *)&data);
  243. } else if (data & 0x8000) {
  244. delay(data & 0x7FFF);
  245. } else if ((data & 0xFF00) == 0) {
  246. u8g_WriteByte(u8g, dev, data & 0xFF);
  247. }
  248. }
  249. u8g_SetAddress(u8g, dev, 1);
  250. }
  251. #endif
  252. static const uint16_t st7789v_init[] = {
  253. ESC_REG(0x0010), ESC_DELAY(10),
  254. ESC_REG(0x0001), ESC_DELAY(200),
  255. ESC_REG(0x0011), ESC_DELAY(120),
  256. ESC_REG(0x0036), 0x00A0,
  257. ESC_REG(0x003A), 0x0055,
  258. ESC_REG(0x002A), 0x0000, 0x0000, 0x0001, 0x003F,
  259. ESC_REG(0x002B), 0x0000, 0x0000, 0x0000, 0x00EF,
  260. ESC_REG(0x00B2), 0x000C, 0x000C, 0x0000, 0x0033, 0x0033,
  261. ESC_REG(0x00B7), 0x0035,
  262. ESC_REG(0x00BB), 0x001F,
  263. ESC_REG(0x00C0), 0x002C,
  264. ESC_REG(0x00C2), 0x0001, 0x00C3,
  265. ESC_REG(0x00C4), 0x0020,
  266. ESC_REG(0x00C6), 0x000F,
  267. ESC_REG(0x00D0), 0x00A4, 0x00A1,
  268. ESC_REG(0x0029),
  269. ESC_REG(0x0011),
  270. ESC_END
  271. };
  272. static const uint16_t ili9328_init[] = {
  273. ESC_REG(0x0001), 0x0100,
  274. ESC_REG(0x0002), 0x0400,
  275. ESC_REG(0x0003), 0x1038,
  276. ESC_REG(0x0004), 0x0000,
  277. ESC_REG(0x0008), 0x0202,
  278. ESC_REG(0x0009), 0x0000,
  279. ESC_REG(0x000A), 0x0000,
  280. ESC_REG(0x000C), 0x0000,
  281. ESC_REG(0x000D), 0x0000,
  282. ESC_REG(0x000F), 0x0000,
  283. ESC_REG(0x0010), 0x0000,
  284. ESC_REG(0x0011), 0x0007,
  285. ESC_REG(0x0012), 0x0000,
  286. ESC_REG(0x0013), 0x0000,
  287. ESC_REG(0x0007), 0x0001,
  288. ESC_DELAY(200),
  289. ESC_REG(0x0010), 0x1690,
  290. ESC_REG(0x0011), 0x0227,
  291. ESC_DELAY(50),
  292. ESC_REG(0x0012), 0x008C,
  293. ESC_DELAY(50),
  294. ESC_REG(0x0013), 0x1500,
  295. ESC_REG(0x0029), 0x0004,
  296. ESC_REG(0x002B), 0x000D,
  297. ESC_DELAY(50),
  298. ESC_REG(0x0050), 0x0000,
  299. ESC_REG(0x0051), 0x00EF,
  300. ESC_REG(0x0052), 0x0000,
  301. ESC_REG(0x0053), 0x013F,
  302. ESC_REG(0x0020), 0x0000,
  303. ESC_REG(0x0021), 0x0000,
  304. ESC_REG(0x0060), 0x2700,
  305. ESC_REG(0x0061), 0x0001,
  306. ESC_REG(0x006A), 0x0000,
  307. ESC_REG(0x0080), 0x0000,
  308. ESC_REG(0x0081), 0x0000,
  309. ESC_REG(0x0082), 0x0000,
  310. ESC_REG(0x0083), 0x0000,
  311. ESC_REG(0x0084), 0x0000,
  312. ESC_REG(0x0085), 0x0000,
  313. ESC_REG(0x0090), 0x0010,
  314. ESC_REG(0x0092), 0x0600,
  315. ESC_REG(0x0007), 0x0133,
  316. ESC_REG(0x0022),
  317. ESC_END
  318. };
  319. static const uint16_t ili9341_init[] = {
  320. ESC_REG(0x0010), ESC_DELAY(10),
  321. ESC_REG(0x0001), ESC_DELAY(200),
  322. ESC_REG(0x0036), 0x00E8,
  323. ESC_REG(0x003A), 0x0055,
  324. ESC_REG(0x002A), 0x0000, 0x0000, 0x0001, 0x003F,
  325. ESC_REG(0x002B), 0x0000, 0x0000, 0x0000, 0x00EF,
  326. ESC_REG(0x00C5), 0x003E, 0x0028,
  327. ESC_REG(0x00C7), 0x0086,
  328. ESC_REG(0x00B1), 0x0000, 0x0018,
  329. ESC_REG(0x00C0), 0x0023,
  330. ESC_REG(0x00C1), 0x0010,
  331. ESC_REG(0x0029),
  332. ESC_REG(0x0011),
  333. ESC_DELAY(100),
  334. ESC_END
  335. };
  336. #if ENABLED(TOUCH_BUTTONS)
  337. static const uint8_t buttonD[] = {
  338. B01111111,B11111111,B11111111,B11111110,
  339. B10000000,B00000000,B00000000,B00000001,
  340. B10000000,B00000000,B00000000,B00000001,
  341. B10000000,B00000000,B00000000,B00000001,
  342. B10000000,B00000000,B00000000,B00000001,
  343. B10000000,B00000000,B00000000,B00000001,
  344. B10000000,B00011000,B00110000,B00000001,
  345. B10000000,B00001100,B01100000,B00000001,
  346. B10000000,B00000110,B11000000,B00000001,
  347. B10000000,B00000011,B10000000,B00000001,
  348. B10000000,B00000011,B10000000,B00000001,
  349. B10000000,B00000110,B11000000,B00000001,
  350. B10000000,B00001100,B01100000,B00000001,
  351. B10000000,B00011000,B00110000,B00000001,
  352. B10000000,B00000000,B00000000,B00000001,
  353. B10000000,B00000000,B00000000,B00000001,
  354. B10000000,B00000000,B00000000,B00000001,
  355. B10000000,B00000000,B00000000,B00000001,
  356. B10000000,B00000000,B00000000,B00000001,
  357. B01111111,B11111111,B11111111,B11111110,
  358. };
  359. #if ENABLED(REVERSE_MENU_DIRECTION)
  360. static const uint8_t buttonA[] = {
  361. B01111111,B11111111,B11111111,B11111110,
  362. B10000000,B00000000,B00000000,B00000001,
  363. B10000000,B00000000,B00000000,B00000001,
  364. B10000000,B00000000,B00000000,B00000001,
  365. B10000000,B00000000,B00000000,B00000001,
  366. B10000000,B11100000,B00000000,B00000001,
  367. B10000000,B11100000,B00000000,B00000001,
  368. B10000000,B11100000,B00000000,B00000001,
  369. B10000000,B11100000,B00000000,B00000001,
  370. B10000000,B11100000,B00111111,B11100001,
  371. B10000111,B11111100,B00111111,B11100001,
  372. B10000011,B11111000,B00000000,B00000001,
  373. B10000001,B11110000,B00000000,B00000001,
  374. B10000000,B11100000,B00000000,B00000001,
  375. B10000000,B01000000,B00000000,B00000001,
  376. B10000000,B00000000,B00000000,B00000001,
  377. B10000000,B00000000,B00000000,B00000001,
  378. B10000000,B00000000,B00000000,B00000001,
  379. B10000000,B00000000,B00000000,B00000001,
  380. B01111111,B11111111,B11111111,B11111110,
  381. };
  382. static const uint8_t buttonB[] = {
  383. B01111111,B11111111,B11111111,B11111110,
  384. B10000000,B00000000,B00000000,B00000001,
  385. B10000000,B00000000,B00000000,B00000001,
  386. B10000000,B00000000,B00000000,B00000001,
  387. B10000000,B00000000,B00000000,B00000001,
  388. B10000000,B01100000,B00000010,B00000001,
  389. B10000000,B01100000,B00000111,B00000001,
  390. B10000000,B01100000,B00001111,B10000001,
  391. B10000000,B01100000,B00011111,B11000001,
  392. B10000111,B11111110,B00111111,B11100001,
  393. B10000111,B11111110,B00000111,B00000001,
  394. B10000000,B01100000,B00000111,B00000001,
  395. B10000000,B01100000,B00000111,B00000001,
  396. B10000000,B01100000,B00000111,B00000001,
  397. B10000000,B01100000,B00000111,B00000001,
  398. B10000000,B00000000,B00000000,B00000001,
  399. B10000000,B00000000,B00000000,B00000001,
  400. B10000000,B00000000,B00000000,B00000001,
  401. B10000000,B00000000,B00000000,B00000001,
  402. B01111111,B11111111,B11111111,B11111110,
  403. };
  404. #else
  405. static const uint8_t buttonA[] = {
  406. B01111111,B11111111,B11111111,B11111110,
  407. B10000000,B00000000,B00000000,B00000001,
  408. B10000000,B00000000,B00000000,B00000001,
  409. B10000000,B00000000,B00000000,B00000001,
  410. B10000000,B00000000,B00000000,B00000001,
  411. B10000000,B01000000,B00000000,B00000001,
  412. B10000000,B11100000,B00000000,B00000001,
  413. B10000001,B11110000,B00000000,B00000001,
  414. B10000011,B11111000,B00000000,B00000001,
  415. B10000111,B11111100,B00111111,B11100001,
  416. B10000000,B11100000,B00111111,B11100001,
  417. B10000000,B11100000,B00000000,B00000001,
  418. B10000000,B11100000,B00000000,B00000001,
  419. B10000000,B11100000,B00000000,B00000001,
  420. B10000000,B11100000,B00000000,B00000001,
  421. B10000000,B00000000,B00000000,B00000001,
  422. B10000000,B00000000,B00000000,B00000001,
  423. B10000000,B00000000,B00000000,B00000001,
  424. B10000000,B00000000,B00000000,B00000001,
  425. B01111111,B11111111,B11111111,B11111110,
  426. };
  427. static const uint8_t buttonB[] = {
  428. B01111111,B11111111,B11111111,B11111110,
  429. B10000000,B00000000,B00000000,B00000001,
  430. B10000000,B00000000,B00000000,B00000001,
  431. B10000000,B00000000,B00000000,B00000001,
  432. B10000000,B00000000,B00000000,B00000001,
  433. B10000000,B01100000,B00000111,B00000001,
  434. B10000000,B01100000,B00000111,B00000001,
  435. B10000000,B01100000,B00000111,B00000001,
  436. B10000000,B01100000,B00000111,B00000001,
  437. B10000111,B11111110,B00000111,B00000001,
  438. B10000111,B11111110,B00111111,B11100001,
  439. B10000000,B01100000,B00011111,B11000001,
  440. B10000000,B01100000,B00001111,B10000001,
  441. B10000000,B01100000,B00000111,B00000001,
  442. B10000000,B01100000,B00000010,B00000001,
  443. B10000000,B00000000,B00000000,B00000001,
  444. B10000000,B00000000,B00000000,B00000001,
  445. B10000000,B00000000,B00000000,B00000001,
  446. B10000000,B00000000,B00000000,B00000001,
  447. B01111111,B11111111,B11111111,B11111110,
  448. };
  449. #endif
  450. static const uint8_t buttonC[] = {
  451. B01111111,B11111111,B11111111,B11111110,
  452. B10000000,B00000000,B00000000,B00000001,
  453. B10000000,B00000000,B00000000,B00000001,
  454. B10000000,B00000000,B00000000,B00000001,
  455. B10000000,B00000000,B00000000,B00000001,
  456. B10000000,B00000000,B00000000,B00000001,
  457. B10000000,B00000000,B00011100,B00000001,
  458. B10000000,B00000100,B00011100,B00000001,
  459. B10000000,B00001100,B00011100,B00000001,
  460. B10000000,B00011111,B11111100,B00000001,
  461. B10000000,B00111111,B11111100,B00000001,
  462. B10000000,B00011111,B11111100,B00000001,
  463. B10000000,B00001100,B00000000,B00000001,
  464. B10000000,B00000100,B00000000,B00000001,
  465. B10000000,B00000000,B00000000,B00000001,
  466. B10000000,B00000000,B00000000,B00000001,
  467. B10000000,B00000000,B00000000,B00000001,
  468. B10000000,B00000000,B00000000,B00000001,
  469. B10000000,B00000000,B00000000,B00000001,
  470. B01111111,B11111111,B11111111,B11111110,
  471. };
  472. void drawImage(const uint8_t *data, u8g_t *u8g, u8g_dev_t *dev, uint16_t length, uint16_t height, uint16_t color) {
  473. uint16_t buffer[128];
  474. for (uint16_t i = 0; i < height; i++) {
  475. uint16_t k = 0;
  476. for (uint16_t j = 0; j < length; j++) {
  477. uint16_t v = TFT_MARLINBG_COLOR;
  478. if (*(data + (i * (length >> 3) + (j >> 3))) & (0x80 >> (j & 7)))
  479. v = color;
  480. else
  481. v = TFT_MARLINBG_COLOR;
  482. buffer[k++] = v; buffer[k++] = v;
  483. }
  484. #ifdef LCD_USE_DMA_FSMC
  485. if (k <= 80) { // generally is... for our buttons
  486. memcpy(&buffer[k], &buffer[0], k * sizeof(uint16_t));
  487. LCD_IO_WriteSequence(buffer, k * sizeof(uint16_t));
  488. }
  489. else {
  490. LCD_IO_WriteSequence(buffer, k);
  491. LCD_IO_WriteSequence(buffer, k);
  492. }
  493. #else
  494. u8g_WriteSequence(u8g, dev, k << 1, (uint8_t *)buffer);
  495. u8g_WriteSequence(u8g, dev, k << 1, (uint8_t *)buffer);
  496. #endif
  497. }
  498. }
  499. #endif // TOUCH_BUTTONS
  500. // Used to fill RGB565 (16bits) background
  501. inline void memset2(const void *ptr, uint16_t fill, size_t cnt) {
  502. uint16_t* wptr = (uint16_t*)ptr;
  503. for (size_t i = 0; i < cnt; i += 2) { *wptr = fill; wptr++; }
  504. }
  505. static bool preinit = true;
  506. static uint8_t page;
  507. uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) {
  508. u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem);
  509. #ifdef LCD_USE_DMA_FSMC
  510. static uint16_t bufferA[512], bufferB[512];
  511. uint16_t* buffer = &bufferA[0];
  512. bool allow_async = true;
  513. #else
  514. uint16_t buffer[WIDTH*2]; // 16-bit RGB 565 pixel line buffer
  515. #endif
  516. switch (msg) {
  517. case U8G_DEV_MSG_INIT:
  518. dev->com_fn(u8g, U8G_COM_MSG_INIT, U8G_SPI_CLK_CYCLE_NONE, &lcd_id);
  519. switch(lcd_id & 0xFFFF) {
  520. case 0x8552: // ST7789V
  521. #ifdef LCD_USE_DMA_FSMC
  522. writeEscSequence(st7789v_init);
  523. #else
  524. writeEscSequence8(u8g, dev, st7789v_init);
  525. #endif
  526. setWindow = setWindow_st7789v;
  527. break;
  528. case 0x9328: // ILI9328
  529. #ifdef LCD_USE_DMA_FSMC
  530. writeEscSequence(ili9328_init);
  531. #else
  532. writeEscSequence16(u8g, dev, ili9328_init);
  533. #endif
  534. setWindow = setWindow_ili9328;
  535. break;
  536. case 0x9341: // ILI9341
  537. #ifdef LCD_USE_DMA_FSMC
  538. writeEscSequence(ili9341_init);
  539. #else
  540. writeEscSequence8(u8g, dev, ili9341_init);
  541. #endif
  542. setWindow = setWindow_st7789v;
  543. break;
  544. case 0x0404: // No connected display on FSMC
  545. lcd_id = 0;
  546. return 0;
  547. case 0xFFFF: // No connected display on SPI
  548. lcd_id = 0;
  549. return 0;
  550. default:
  551. if (lcd_id && 0xFF000000)
  552. setWindow = setWindow_st7789v;
  553. else
  554. setWindow = setWindow_ili9328;
  555. break;
  556. }
  557. if (preinit) {
  558. preinit = false;
  559. return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg);
  560. }
  561. // Clear Screen
  562. setWindow(u8g, dev, 0, 0, LCD_FULL_PIXEL_WIDTH - 1, LCD_FULL_PIXEL_HEIGHT - 1);
  563. #ifdef LCD_USE_DMA_FSMC
  564. LCD_IO_WriteMultiple(TFT_MARLINBG_COLOR, LCD_FULL_PIXEL_WIDTH * LCD_FULL_PIXEL_HEIGHT);
  565. #else
  566. memset2(buffer, TFT_MARLINBG_COLOR, 160);
  567. for (uint16_t i = 0; i < 960; i++)
  568. u8g_WriteSequence(u8g, dev, 160, (uint8_t *)buffer);
  569. #endif
  570. // bottom line and buttons
  571. #if ENABLED(TOUCH_BUTTONS)
  572. setWindow(u8g, dev, 10, 170, 309, 171);
  573. #ifdef LCD_USE_DMA_FSMC
  574. LCD_IO_WriteMultiple(TFT_DISABLED_COLOR, 600);
  575. #else
  576. memset2(buffer, TFT_DISABLED_COLOR, 150);
  577. for (uint8_t i = 8; i--;)
  578. u8g_WriteSequence(u8g, dev, 150, (uint8_t *)buffer);
  579. #endif
  580. setWindow(u8g, dev, 14, 185, 77, 224);
  581. drawImage(buttonD, u8g, dev, 32, 20, TFT_BTCANCEL_COLOR);
  582. setWindow(u8g, dev, 90, 185, 153, 224);
  583. drawImage(buttonA, u8g, dev, 32, 20, TFT_BTARROWS_COLOR);
  584. setWindow(u8g, dev, 166, 185, 229, 224);
  585. drawImage(buttonB, u8g, dev, 32, 20, TFT_BTARROWS_COLOR);
  586. setWindow(u8g, dev, 242, 185, 305, 224);
  587. drawImage(buttonC, u8g, dev, 32, 20, TFT_BTOKMENU_COLOR);
  588. #endif // TOUCH_BUTTONS
  589. return 0;
  590. case U8G_DEV_MSG_STOP: preinit = true; break;
  591. case U8G_DEV_MSG_PAGE_FIRST:
  592. page = 0;
  593. setWindow(u8g, dev, X_LO, Y_LO, X_HI, Y_HI);
  594. break;
  595. case U8G_DEV_MSG_PAGE_NEXT:
  596. if (++page > (HEIGHT / PAGE_HEIGHT)) return 1;
  597. LOOP_L_N(y, PAGE_HEIGHT) {
  598. uint32_t k = 0;
  599. #ifdef LCD_USE_DMA_FSMC
  600. buffer = (y & 1) ? bufferB : bufferA;
  601. #endif
  602. for (uint16_t i = 0; i < (uint32_t)pb->width; i++) {
  603. const uint8_t b = *(((uint8_t *)pb->buf) + i);
  604. const uint16_t c = TEST(b, y) ? TFT_MARLINUI_COLOR : TFT_MARLINBG_COLOR;
  605. buffer[k++] = c; buffer[k++] = c;
  606. }
  607. #ifdef LCD_USE_DMA_FSMC
  608. memcpy(&buffer[256], &buffer[0], 512);
  609. if (allow_async) {
  610. if (y > 0 || page > 1) LCD_IO_WaitSequence_Async();
  611. if (y == 7 && page == 8)
  612. LCD_IO_WriteSequence(buffer, 512); // last line of last page
  613. else
  614. LCD_IO_WriteSequence_Async(buffer, 512);
  615. }
  616. else
  617. LCD_IO_WriteSequence(buffer, 512);
  618. #else
  619. uint8_t* bufptr = (uint8_t*) buffer;
  620. for (uint8_t i = 2; i--;) {
  621. u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[0]);
  622. u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[WIDTH]);
  623. u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[WIDTH*2]);
  624. u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[WIDTH*3]);
  625. }
  626. #endif
  627. }
  628. break;
  629. case U8G_DEV_MSG_SLEEP_ON:
  630. // Enter Sleep Mode (10h)
  631. return 1;
  632. case U8G_DEV_MSG_SLEEP_OFF:
  633. // Sleep Out (11h)
  634. return 1;
  635. }
  636. return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg);
  637. }
  638. U8G_PB_DEV(u8g_dev_tft_320x240_upscale_from_128x64, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_tft_320x240_upscale_from_128x64_fn, U8G_COM_HAL_FSMC_FN);
  639. #endif // HAS_GRAPHICAL_LCD && FSMC_CS