qp_internal.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Copyright 2023 Nick Brassel (@tzarc)
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "qp_internal.h"
  4. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5. // Quantum Painter Core API: device registration
  6. enum {
  7. // Work out how many devices we're actually going to be instantiating
  8. // NOTE: We intentionally do not include surfaces here, despite them conforming to the same API.
  9. QP_NUM_DEVICES = (ILI9163_NUM_DEVICES) // ILI9163
  10. + (ILI9341_NUM_DEVICES) // ILI9341
  11. + (ILI9488_NUM_DEVICES) // ILI9488
  12. + (ST7789_NUM_DEVICES) // ST7789
  13. + (ST7735_NUM_DEVICES) // ST7735
  14. + (GC9A01_NUM_DEVICES) // GC9A01
  15. + (SSD1351_NUM_DEVICES) // SSD1351
  16. };
  17. static painter_device_t qp_devices[QP_NUM_DEVICES] = {NULL};
  18. bool qp_internal_register_device(painter_device_t driver) {
  19. for (uint8_t i = 0; i < QP_NUM_DEVICES; i++) {
  20. if (qp_devices[i] == NULL) {
  21. qp_devices[i] = driver;
  22. return true;
  23. }
  24. }
  25. // We should never get here -- someone has screwed up their device counts during config
  26. qp_dprintf("qp_internal_register_device: no more space for devices!\n");
  27. return false;
  28. }
  29. #if (QUANTUM_PAINTER_DISPLAY_TIMEOUT) > 0
  30. static void qp_internal_display_timeout_task(void) {
  31. // Handle power on/off state
  32. static bool display_on = true;
  33. bool should_change_display_state = false;
  34. bool target_display_state = false;
  35. if (last_input_activity_elapsed() < (QUANTUM_PAINTER_DISPLAY_TIMEOUT)) {
  36. should_change_display_state = display_on == false;
  37. target_display_state = true;
  38. } else {
  39. should_change_display_state = display_on == true;
  40. target_display_state = false;
  41. }
  42. if (should_change_display_state) {
  43. for (uint8_t i = 0; i < QP_NUM_DEVICES; i++) {
  44. if (qp_devices[i] != NULL) {
  45. qp_power(qp_devices[i], target_display_state);
  46. }
  47. }
  48. display_on = target_display_state;
  49. }
  50. }
  51. #endif // (QUANTUM_PAINTER_DISPLAY_TIMEOUT) > 0
  52. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  53. // Quantum Painter Core API: qp_internal_task
  54. _Static_assert((QUANTUM_PAINTER_TASK_THROTTLE) > 0 && (QUANTUM_PAINTER_TASK_THROTTLE) < 1000, "QUANTUM_PAINTER_TASK_THROTTLE must be between 1 and 999");
  55. void qp_internal_task(void) {
  56. // Perform throttling of the internal processing of Quantum Painter
  57. static uint32_t last_tick = 0;
  58. uint32_t now = timer_read32();
  59. if (TIMER_DIFF_32(now, last_tick) < (QUANTUM_PAINTER_TASK_THROTTLE)) {
  60. return;
  61. }
  62. last_tick = now;
  63. #if (QUANTUM_PAINTER_DISPLAY_TIMEOUT) > 0
  64. qp_internal_display_timeout_task();
  65. #endif // (QUANTUM_PAINTER_DISPLAY_TIMEOUT) > 0
  66. // Handle animations
  67. void qp_internal_animation_tick(void);
  68. qp_internal_animation_tick();
  69. #ifdef QUANTUM_PAINTER_LVGL_INTEGRATION_ENABLE
  70. // Run LVGL ticks
  71. void qp_lvgl_internal_tick(void);
  72. qp_lvgl_internal_tick();
  73. #endif
  74. // Flush (render) dirty regions to corresponding displays
  75. #if !defined(QUANTUM_PAINTER_DEBUG_ENABLE_FLUSH_TASK_OUTPUT)
  76. bool old_debug_state = debug_enable;
  77. debug_enable = false;
  78. #endif // defined(QUANTUM_PAINTER_DEBUG_ENABLE_FLUSH_TASK_OUTPUT)
  79. for (uint8_t i = 0; i < QP_NUM_DEVICES; i++) {
  80. if (qp_devices[i] != NULL) {
  81. qp_flush(qp_devices[i]);
  82. }
  83. }
  84. #if !defined(QUANTUM_PAINTER_DEBUG_ENABLE_FLUSH_TASK_OUTPUT)
  85. debug_enable = old_debug_state;
  86. #endif // defined(QUANTUM_PAINTER_DEBUG_ENABLE_FLUSH_TASK_OUTPUT)
  87. }