My Marlin configs for Fabrikator Mini and CTC i3 Pro B
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

tft_queue.cpp 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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 <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. #include "../../inc/MarlinConfig.h"
  23. #if HAS_GRAPHICAL_TFT
  24. #include "tft_queue.h"
  25. #include "tft.h"
  26. #include "tft_image.h"
  27. uint8_t TFT_Queue::queue[];
  28. uint8_t *TFT_Queue::end_of_queue = queue;
  29. uint8_t *TFT_Queue::current_task = nullptr;
  30. uint8_t *TFT_Queue::last_task = nullptr;
  31. uint8_t *TFT_Queue::last_parameter = nullptr;
  32. void TFT_Queue::reset() {
  33. tft.abort();
  34. end_of_queue = queue;
  35. current_task = nullptr;
  36. last_task = nullptr;
  37. last_parameter = nullptr;
  38. }
  39. void TFT_Queue::async() {
  40. if (!current_task) return;
  41. queueTask_t *task = (queueTask_t *)current_task;
  42. // Check IO busy status
  43. if (tft.is_busy()) return;
  44. if (task->state == TASK_STATE_COMPLETED) {
  45. task = (queueTask_t *)task->nextTask;
  46. current_task = (uint8_t *)task;
  47. }
  48. finish_sketch();
  49. switch (task->type) {
  50. case TASK_END_OF_QUEUE: reset(); break;
  51. case TASK_FILL: fill(task); break;
  52. case TASK_CANVAS: canvas(task); break;
  53. }
  54. }
  55. void TFT_Queue::finish_sketch() {
  56. if (!last_task) return;
  57. queueTask_t *task = (queueTask_t *)last_task;
  58. if (task->state == TASK_STATE_SKETCH) {
  59. *end_of_queue = TASK_END_OF_QUEUE;
  60. task->nextTask = end_of_queue;
  61. task->state = TASK_STATE_READY;
  62. if (!current_task) current_task = (uint8_t *)task;
  63. }
  64. }
  65. void TFT_Queue::fill(queueTask_t *task) {
  66. uint16_t count;
  67. parametersFill_t *task_parameters = (parametersFill_t *)(((uint8_t *)task) + sizeof(queueTask_t));
  68. if (task->state == TASK_STATE_READY) {
  69. tft.set_window(task_parameters->x, task_parameters->y, task_parameters->x + task_parameters->width - 1, task_parameters->y + task_parameters->height - 1);
  70. task->state = TASK_STATE_IN_PROGRESS;
  71. }
  72. if (task_parameters->count > 65535) {
  73. count = 65535;
  74. task_parameters->count -= 65535;
  75. }
  76. else {
  77. count = task_parameters->count;
  78. task_parameters->count = 0;
  79. task->state = TASK_STATE_COMPLETED;
  80. }
  81. tft.write_multiple(task_parameters->color, count);
  82. }
  83. void TFT_Queue::canvas(queueTask_t *task) {
  84. parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)task) + sizeof(queueTask_t));
  85. uint16_t i;
  86. uint8_t *item = ((uint8_t *)task_parameters) + sizeof(parametersCanvas_t);
  87. if (task->state == TASK_STATE_READY) {
  88. task->state = TASK_STATE_IN_PROGRESS;
  89. Canvas.New(task_parameters->x, task_parameters->y, task_parameters->width, task_parameters->height);
  90. }
  91. Canvas.Continue();
  92. for (i = 0; i < task_parameters->count; i++) {
  93. switch (*item) {
  94. case CANVAS_SET_BACKGROUND:
  95. Canvas.SetBackground(((parametersCanvasBackground_t *)item)->color);
  96. break;
  97. case CANVAS_ADD_TEXT:
  98. Canvas.AddText(((parametersCanvasText_t *)item)->x, ((parametersCanvasText_t *)item)->y, ((parametersCanvasText_t *)item)->color, item + sizeof(parametersCanvasText_t), ((parametersCanvasText_t *)item)->maxWidth);
  99. break;
  100. case CANVAS_ADD_IMAGE:
  101. MarlinImage image;
  102. uint16_t *colors;
  103. image = ((parametersCanvasImage_t *)item)->image;
  104. colors = (uint16_t *)(item + sizeof(parametersCanvasImage_t));
  105. Canvas.AddImage(((parametersCanvasImage_t *)item)->x, ((parametersCanvasImage_t *)item)->y, image, colors);
  106. break;
  107. case CANVAS_ADD_BAR:
  108. Canvas.AddBar(((parametersCanvasBar_t *)item)->x, ((parametersCanvasBar_t *)item)->y, ((parametersCanvasBar_t *)item)->width, ((parametersCanvasBar_t *)item)->height, ((parametersCanvasBar_t *)item)->color);
  109. break;
  110. case CANVAS_ADD_RECTANGLE:
  111. Canvas.AddRectangle(((parametersCanvasRectangle_t *)item)->x, ((parametersCanvasRectangle_t *)item)->y, ((parametersCanvasRectangle_t *)item)->width, ((parametersCanvasRectangle_t *)item)->height, ((parametersCanvasRectangle_t *)item)->color);
  112. break;
  113. }
  114. item = ((parametersCanvasBackground_t *)item)->nextParameter;
  115. }
  116. if (Canvas.ToScreen()) task->state = TASK_STATE_COMPLETED;
  117. }
  118. void TFT_Queue::fill(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) {
  119. finish_sketch();
  120. queueTask_t *task = (queueTask_t *)end_of_queue;
  121. last_task = (uint8_t *)task;
  122. end_of_queue += sizeof(queueTask_t);
  123. parametersFill_t *task_parameters = (parametersFill_t *)end_of_queue;
  124. end_of_queue += sizeof(parametersFill_t);
  125. last_parameter = end_of_queue;
  126. task_parameters->x = x;
  127. task_parameters->y = y;
  128. task_parameters->width = width;
  129. task_parameters->height = height;
  130. task_parameters->color = ENDIAN_COLOR(color);
  131. task_parameters->count = width * height;
  132. *end_of_queue = TASK_END_OF_QUEUE;
  133. task->nextTask = end_of_queue;
  134. task->state = TASK_STATE_READY;
  135. task->type = TASK_FILL;
  136. if (!current_task) current_task = (uint8_t *)task;
  137. }
  138. void TFT_Queue::canvas(uint16_t x, uint16_t y, uint16_t width, uint16_t height) {
  139. finish_sketch();
  140. queueTask_t *task = (queueTask_t *)end_of_queue;
  141. last_task = (uint8_t *) task;
  142. task->state = TASK_STATE_SKETCH;
  143. task->type = TASK_CANVAS;
  144. task->nextTask = nullptr;
  145. end_of_queue += sizeof(queueTask_t);
  146. parametersCanvas_t *task_parameters = (parametersCanvas_t *)end_of_queue;
  147. end_of_queue += sizeof(parametersCanvas_t);
  148. last_parameter = end_of_queue;
  149. task_parameters->x = x;
  150. task_parameters->y = y;
  151. task_parameters->width = width;
  152. task_parameters->height = height;
  153. task_parameters->count = 0;
  154. if (!current_task) current_task = (uint8_t *)task;
  155. }
  156. void TFT_Queue::set_background(uint16_t color) {
  157. handle_queue_overflow(sizeof(parametersCanvasBackground_t));
  158. parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t));
  159. parametersCanvasBackground_t *parameters = (parametersCanvasBackground_t *)end_of_queue;
  160. last_parameter = end_of_queue;
  161. parameters->type = CANVAS_SET_BACKGROUND;
  162. parameters->color = ENDIAN_COLOR(color);
  163. end_of_queue += sizeof(parametersCanvasBackground_t);
  164. task_parameters->count++;
  165. parameters->nextParameter = end_of_queue;
  166. }
  167. #define QUEUE_SAFETY_FREE_SPACE 100
  168. void TFT_Queue::handle_queue_overflow(uint16_t sizeNeeded) {
  169. if (uintptr_t(end_of_queue) + sizeNeeded + (QUEUE_SAFETY_FREE_SPACE) - uintptr_t(queue) >= TFT_QUEUE_SIZE) {
  170. end_of_queue = queue;
  171. ((parametersCanvasText_t *)last_parameter)->nextParameter = end_of_queue;
  172. }
  173. }
  174. void TFT_Queue::add_text(uint16_t x, uint16_t y, uint16_t color, const uint8_t *string, uint16_t maxWidth) {
  175. handle_queue_overflow(sizeof(parametersCanvasText_t) + maxWidth);
  176. parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t));
  177. parametersCanvasText_t *parameters = (parametersCanvasText_t *)end_of_queue;
  178. last_parameter = end_of_queue;
  179. const uint8_t *pointer = string;
  180. parameters->type = CANVAS_ADD_TEXT;
  181. parameters->x = x;
  182. parameters->y = y;
  183. parameters->color = ENDIAN_COLOR(color);
  184. parameters->stringLength = 0;
  185. parameters->maxWidth = maxWidth;
  186. end_of_queue += sizeof(parametersCanvasText_t);
  187. /* TODO: Deal with maxWidth */
  188. while ((*(end_of_queue++) = *pointer++) != 0x00);
  189. parameters->nextParameter = end_of_queue;
  190. parameters->stringLength = pointer - string;
  191. task_parameters->count++;
  192. }
  193. void TFT_Queue::add_image(int16_t x, int16_t y, MarlinImage image, uint16_t *colors) {
  194. handle_queue_overflow(sizeof(parametersCanvasImage_t));
  195. parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t));
  196. parametersCanvasImage_t *parameters = (parametersCanvasImage_t *)end_of_queue;
  197. last_parameter = end_of_queue;
  198. parameters->type = CANVAS_ADD_IMAGE;
  199. parameters->x = x;
  200. parameters->y = y;
  201. parameters->image = image;
  202. end_of_queue += sizeof(parametersCanvasImage_t);
  203. task_parameters->count++;
  204. parameters->nextParameter = end_of_queue;
  205. colorMode_t color_mode = Images[image].colorMode;
  206. if (color_mode == HIGHCOLOR) return;
  207. uint16_t *color = (uint16_t *)end_of_queue;
  208. uint8_t color_count = 0;
  209. switch (color_mode) {
  210. case GREYSCALE1: color_count = 1; break;
  211. case GREYSCALE2: color_count = 3; break;
  212. case GREYSCALE4: color_count = 15; break;
  213. default: break;
  214. }
  215. uint16_t tmp;
  216. while (color_count--) {
  217. tmp = *colors++;
  218. *color++ = ENDIAN_COLOR(tmp);
  219. }
  220. end_of_queue = (uint8_t *)color;
  221. parameters->nextParameter = end_of_queue;
  222. }
  223. uint16_t gradient(uint16_t colorA, uint16_t colorB, uint16_t factor) {
  224. uint16_t red, green, blue;
  225. red = ( RED(colorA) * factor + RED(colorB) * (256 - factor)) >> 8;
  226. green = (GREEN(colorA) * factor + GREEN(colorB) * (256 - factor)) >> 8;
  227. blue = ( BLUE(colorA) * factor + BLUE(colorB) * (256 - factor)) >> 8;
  228. return RGB(red, green, blue);
  229. }
  230. void TFT_Queue::add_image(int16_t x, int16_t y, MarlinImage image, uint16_t color_main, uint16_t color_background, uint16_t color_shadow) {
  231. uint16_t colors[16];
  232. colorMode_t color_mode = Images[image].colorMode;
  233. uint16_t i;
  234. switch (color_mode) {
  235. case GREYSCALE1:
  236. colors[1] = color_main;
  237. break;
  238. case GREYSCALE2:
  239. for (i = 1; i < 4; i++)
  240. colors[i] = gradient(color_main, color_background, (i << 8) / 3);
  241. break;
  242. case GREYSCALE4:
  243. for (i = 1; i < 8; i++)
  244. colors[i] = gradient(color_background, color_shadow, i << 5);
  245. for (i = 8; i < 16; i++)
  246. colors[i] = gradient(color_main, color_background, ((i - 8) << 8) / 7);
  247. break;
  248. default:
  249. break;
  250. }
  251. add_image(x, y, image, colors + 1);
  252. }
  253. void TFT_Queue::add_bar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) {
  254. handle_queue_overflow(sizeof(parametersCanvasBar_t));
  255. parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t));
  256. parametersCanvasBar_t *parameters = (parametersCanvasBar_t *)end_of_queue;
  257. last_parameter = end_of_queue;
  258. parameters->type = CANVAS_ADD_BAR;
  259. parameters->x = x;
  260. parameters->y = y;
  261. parameters->width = width;
  262. parameters->height = height;
  263. parameters->color = ENDIAN_COLOR(color);
  264. end_of_queue += sizeof(parametersCanvasBar_t);
  265. task_parameters->count++;
  266. parameters->nextParameter = end_of_queue;
  267. }
  268. void TFT_Queue::add_rectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) {
  269. handle_queue_overflow(sizeof(parametersCanvasRectangle_t));
  270. parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t));
  271. parametersCanvasRectangle_t *parameters = (parametersCanvasRectangle_t *)end_of_queue;
  272. last_parameter = end_of_queue;
  273. parameters->type = CANVAS_ADD_RECTANGLE;
  274. parameters->x = x;
  275. parameters->y = y;
  276. parameters->width = width;
  277. parameters->height = height;
  278. parameters->color = ENDIAN_COLOR(color);
  279. end_of_queue += sizeof(parametersCanvasRectangle_t);
  280. task_parameters->count++;
  281. parameters->nextParameter = end_of_queue;
  282. }
  283. #endif // HAS_GRAPHICAL_TFT