summaryrefslogtreecommitdiff
path: root/quantum/painter/qp_internal.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/painter/qp_internal.c')
-rw-r--r--quantum/painter/qp_internal.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/quantum/painter/qp_internal.c b/quantum/painter/qp_internal.c
new file mode 100644
index 0000000000..ea23aef7c3
--- /dev/null
+++ b/quantum/painter/qp_internal.c
@@ -0,0 +1,96 @@
+// Copyright 2023 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "qp_internal.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Quantum Painter Core API: device registration
+
+enum {
+ // Work out how many devices we're actually going to be instantiating
+ // NOTE: We intentionally do not include surfaces here, despite them conforming to the same API.
+ QP_NUM_DEVICES = (ILI9163_NUM_DEVICES) // ILI9163
+ + (ILI9341_NUM_DEVICES) // ILI9341
+ + (ILI9488_NUM_DEVICES) // ILI9488
+ + (ST7789_NUM_DEVICES) // ST7789
+ + (ST7735_NUM_DEVICES) // ST7735
+ + (GC9A01_NUM_DEVICES) // GC9A01
+ + (SSD1351_NUM_DEVICES) // SSD1351
+};
+
+static painter_device_t qp_devices[QP_NUM_DEVICES] = {NULL};
+
+bool qp_internal_register_device(painter_device_t driver) {
+ for (uint8_t i = 0; i < QP_NUM_DEVICES; i++) {
+ if (qp_devices[i] == NULL) {
+ qp_devices[i] = driver;
+ return true;
+ }
+ }
+
+ // We should never get here -- someone has screwed up their device counts during config
+ qp_dprintf("qp_internal_register_device: no more space for devices!\n");
+ return false;
+}
+
+#if (QUANTUM_PAINTER_DISPLAY_TIMEOUT) > 0
+static void qp_internal_display_timeout_task(void) {
+ // Handle power on/off state
+ static bool display_on = true;
+ bool should_change_display_state = false;
+ bool target_display_state = false;
+ if (last_input_activity_elapsed() < (QUANTUM_PAINTER_DISPLAY_TIMEOUT)) {
+ should_change_display_state = display_on == false;
+ target_display_state = true;
+ } else {
+ should_change_display_state = display_on == true;
+ target_display_state = false;
+ }
+
+ if (should_change_display_state) {
+ for (uint8_t i = 0; i < QP_NUM_DEVICES; i++) {
+ if (qp_devices[i] != NULL) {
+ qp_power(qp_devices[i], target_display_state);
+ }
+ }
+
+ display_on = target_display_state;
+ }
+}
+#endif // (QUANTUM_PAINTER_DISPLAY_TIMEOUT) > 0
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Quantum Painter Core API: qp_internal_task
+
+_Static_assert((QUANTUM_PAINTER_TASK_THROTTLE) > 0 && (QUANTUM_PAINTER_TASK_THROTTLE) < 1000, "QUANTUM_PAINTER_TASK_THROTTLE must be between 1 and 999");
+
+void qp_internal_task(void) {
+ // Perform throttling of the internal processing of Quantum Painter
+ static uint32_t last_tick = 0;
+ uint32_t now = timer_read32();
+ if (TIMER_DIFF_32(now, last_tick) < (QUANTUM_PAINTER_TASK_THROTTLE)) {
+ return;
+ }
+ last_tick = now;
+
+#if (QUANTUM_PAINTER_DISPLAY_TIMEOUT) > 0
+ qp_internal_display_timeout_task();
+#endif // (QUANTUM_PAINTER_DISPLAY_TIMEOUT) > 0
+
+ // Handle animations
+ void qp_internal_animation_tick(void);
+ qp_internal_animation_tick();
+
+#ifdef QUANTUM_PAINTER_LVGL_INTEGRATION_ENABLE
+ // Run LVGL ticks
+ void qp_lvgl_internal_tick(void);
+ qp_lvgl_internal_tick();
+#endif
+
+ // Flush (render) dirty regions to corresponding displays
+ for (uint8_t i = 0; i < QP_NUM_DEVICES; i++) {
+ if (qp_devices[i] != NULL) {
+ qp_flush(qp_devices[i]);
+ }
+ }
+}