diff options
| -rw-r--r-- | docs/quantum_painter.md | 22 | ||||
| -rw-r--r-- | drivers/painter/gc9a01/qp_gc9a01.c | 7 | ||||
| -rw-r--r-- | drivers/painter/ili9xxx/qp_ili9163.c | 8 | ||||
| -rw-r--r-- | drivers/painter/ili9xxx/qp_ili9341.c | 8 | ||||
| -rw-r--r-- | drivers/painter/ili9xxx/qp_ili9488.c | 8 | ||||
| -rw-r--r-- | drivers/painter/ssd1351/qp_ssd1351.c | 8 | ||||
| -rw-r--r-- | drivers/painter/st77xx/qp_st7735.c | 8 | ||||
| -rw-r--r-- | drivers/painter/st77xx/qp_st7789.c | 8 | ||||
| -rw-r--r-- | quantum/painter/qp.h | 36 | ||||
| -rw-r--r-- | quantum/painter/qp_draw_image.c | 14 | ||||
| -rw-r--r-- | quantum/painter/qp_internal.c | 96 | ||||
| -rw-r--r-- | quantum/painter/qp_internal_driver.h | 7 | ||||
| -rw-r--r-- | quantum/painter/rules.mk | 1 | 
13 files changed, 199 insertions, 32 deletions
| diff --git a/docs/quantum_painter.md b/docs/quantum_painter.md index ac37053c79..acb9d1d384 100644 --- a/docs/quantum_painter.md +++ b/docs/quantum_painter.md @@ -32,16 +32,18 @@ Supported devices:  ## Quantum Painter Configuration :id=quantum-painter-config -| Option                                   | Default | Purpose                                                                                                                                     | -|------------------------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------| -| `QUANTUM_PAINTER_NUM_IMAGES`             | `8`     | The maximum number of images/animations that can be loaded at any one time.                                                                 | -| `QUANTUM_PAINTER_NUM_FONTS`              | `4`     | The maximum number of fonts that can be loaded at any one time.                                                                             | -| `QUANTUM_PAINTER_CONCURRENT_ANIMATIONS`  | `4`     | The maximum number of animations that can be executed at the same time.                                                                     | -| `QUANTUM_PAINTER_LOAD_FONTS_TO_RAM`      | `FALSE` | Whether or not fonts should be loaded to RAM. Relevant for fonts stored in off-chip persistent storage, such as external flash.             | -| `QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE`    | `32`    | The limit of the amount of pixel data that can be transmitted in one transaction to the display. Higher values require more RAM on the MCU. | -| `QUANTUM_PAINTER_SUPPORTS_256_PALETTE`   | `FALSE` | If 256-color palettes are supported. Requires significantly more RAM on the MCU.                                                            | -| `QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS` | `FALSE` | If native color range is supported. Requires significantly more RAM on the MCU.                                                             | -| `QUANTUM_PAINTER_DEBUG`                  | _unset_ | Prints out significant amounts of debugging information to CONSOLE output. Significant performance degradation, use only for debugging.     | +| Option                                   | Default | Purpose                                                                                                                                                                                      | +|------------------------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `QUANTUM_PAINTER_DISPLAY_TIMEOUT`        | `30000` | This controls the amount of time (in milliseconds) that all displays will remain on after the last user input. If set to `0`, the display will remain on indefinitely.                       | +| `QUANTUM_PAINTER_TASK_THROTTLE`          | `1`     | This controls the amount of time (in milliseconds) that the Quantum Painter internal task will wait between each execution. Affects animations, display timeout, and LVGL timing if enabled. | +| `QUANTUM_PAINTER_NUM_IMAGES`             | `8`     | The maximum number of images/animations that can be loaded at any one time.                                                                                                                  | +| `QUANTUM_PAINTER_NUM_FONTS`              | `4`     | The maximum number of fonts that can be loaded at any one time.                                                                                                                              | +| `QUANTUM_PAINTER_CONCURRENT_ANIMATIONS`  | `4`     | The maximum number of animations that can be executed at the same time.                                                                                                                      | +| `QUANTUM_PAINTER_LOAD_FONTS_TO_RAM`      | `FALSE` | Whether or not fonts should be loaded to RAM. Relevant for fonts stored in off-chip persistent storage, such as external flash.                                                              | +| `QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE`    | `32`    | The limit of the amount of pixel data that can be transmitted in one transaction to the display. Higher values require more RAM on the MCU.                                                  | +| `QUANTUM_PAINTER_SUPPORTS_256_PALETTE`   | `FALSE` | If 256-color palettes are supported. Requires significantly more RAM on the MCU.                                                                                                             | +| `QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS` | `FALSE` | If native color range is supported. Requires significantly more RAM on the MCU.                                                                                                              | +| `QUANTUM_PAINTER_DEBUG`                  | _unset_ | Prints out significant amounts of debugging information to CONSOLE output. Significant performance degradation, use only for debugging.                                                      |  Drivers have their own set of configurable options, and are described in their respective sections. diff --git a/drivers/painter/gc9a01/qp_gc9a01.c b/drivers/painter/gc9a01/qp_gc9a01.c index 5d079435c6..56140fa50e 100644 --- a/drivers/painter/gc9a01/qp_gc9a01.c +++ b/drivers/painter/gc9a01/qp_gc9a01.c @@ -1,4 +1,5 @@  // Copyright 2021 Paul Cotter (@gr1mr3aver) +// Copyright 2023 Nick Brassel (@tzarc)  // SPDX-License-Identifier: GPL-2.0-or-later  #include <wait.h> @@ -141,6 +142,12 @@ painter_device_t qp_gc9a01_make_spi_device(uint16_t panel_width, uint16_t panel_              driver->spi_dc_reset_config.spi_config.mode            = spi_mode;              driver->spi_dc_reset_config.dc_pin                     = dc_pin;              driver->spi_dc_reset_config.reset_pin                  = reset_pin; + +            if (!qp_internal_register_device((painter_device_t)driver)) { +                memset(driver, 0, sizeof(tft_panel_dc_reset_painter_device_t)); +                return NULL; +            } +              return (painter_device_t)driver;          }      } diff --git a/drivers/painter/ili9xxx/qp_ili9163.c b/drivers/painter/ili9xxx/qp_ili9163.c index af37686631..917650953d 100644 --- a/drivers/painter/ili9xxx/qp_ili9163.c +++ b/drivers/painter/ili9xxx/qp_ili9163.c @@ -1,4 +1,4 @@ -// Copyright 2021 Nick Brassel (@tzarc) +// Copyright 2021-2023 Nick Brassel (@tzarc)  // SPDX-License-Identifier: GPL-2.0-or-later  #include "qp_internal.h" @@ -110,6 +110,12 @@ painter_device_t qp_ili9163_make_spi_device(uint16_t panel_width, uint16_t panel              driver->spi_dc_reset_config.spi_config.mode            = spi_mode;              driver->spi_dc_reset_config.dc_pin                     = dc_pin;              driver->spi_dc_reset_config.reset_pin                  = reset_pin; + +            if (!qp_internal_register_device((painter_device_t)driver)) { +                memset(driver, 0, sizeof(tft_panel_dc_reset_painter_device_t)); +                return NULL; +            } +              return (painter_device_t)driver;          }      } diff --git a/drivers/painter/ili9xxx/qp_ili9341.c b/drivers/painter/ili9xxx/qp_ili9341.c index aca3809912..ed6766666c 100644 --- a/drivers/painter/ili9xxx/qp_ili9341.c +++ b/drivers/painter/ili9xxx/qp_ili9341.c @@ -1,4 +1,4 @@ -// Copyright 2021 Nick Brassel (@tzarc) +// Copyright 2021-2023 Nick Brassel (@tzarc)  // SPDX-License-Identifier: GPL-2.0-or-later  #include "qp_internal.h" @@ -117,6 +117,12 @@ painter_device_t qp_ili9341_make_spi_device(uint16_t panel_width, uint16_t panel              driver->spi_dc_reset_config.spi_config.mode            = spi_mode;              driver->spi_dc_reset_config.dc_pin                     = dc_pin;              driver->spi_dc_reset_config.reset_pin                  = reset_pin; + +            if (!qp_internal_register_device((painter_device_t)driver)) { +                memset(driver, 0, sizeof(tft_panel_dc_reset_painter_device_t)); +                return NULL; +            } +              return (painter_device_t)driver;          }      } diff --git a/drivers/painter/ili9xxx/qp_ili9488.c b/drivers/painter/ili9xxx/qp_ili9488.c index e51f0e1d51..3740666583 100644 --- a/drivers/painter/ili9xxx/qp_ili9488.c +++ b/drivers/painter/ili9xxx/qp_ili9488.c @@ -1,4 +1,4 @@ -// Copyright 2021 Nick Brassel (@tzarc) +// Copyright 2021-2023 Nick Brassel (@tzarc)  // SPDX-License-Identifier: GPL-2.0-or-later  #include "qp_internal.h" @@ -110,6 +110,12 @@ painter_device_t qp_ili9488_make_spi_device(uint16_t panel_width, uint16_t panel              driver->spi_dc_reset_config.spi_config.mode            = spi_mode;              driver->spi_dc_reset_config.dc_pin                     = dc_pin;              driver->spi_dc_reset_config.reset_pin                  = reset_pin; + +            if (!qp_internal_register_device((painter_device_t)driver)) { +                memset(driver, 0, sizeof(tft_panel_dc_reset_painter_device_t)); +                return NULL; +            } +              return (painter_device_t)driver;          }      } diff --git a/drivers/painter/ssd1351/qp_ssd1351.c b/drivers/painter/ssd1351/qp_ssd1351.c index 548785a1bd..7ee249752b 100644 --- a/drivers/painter/ssd1351/qp_ssd1351.c +++ b/drivers/painter/ssd1351/qp_ssd1351.c @@ -1,4 +1,4 @@ -// Copyright 2021 Nick Brassel (@tzarc) +// Copyright 2021-2023 Nick Brassel (@tzarc)  // SPDX-License-Identifier: GPL-2.0-or-later  #include "qp_internal.h" @@ -114,6 +114,12 @@ painter_device_t qp_ssd1351_make_spi_device(uint16_t panel_width, uint16_t panel              driver->spi_dc_reset_config.spi_config.mode            = spi_mode;              driver->spi_dc_reset_config.dc_pin                     = dc_pin;              driver->spi_dc_reset_config.reset_pin                  = reset_pin; + +            if (!qp_internal_register_device((painter_device_t)driver)) { +                memset(driver, 0, sizeof(tft_panel_dc_reset_painter_device_t)); +                return NULL; +            } +              return (painter_device_t)driver;          }      } diff --git a/drivers/painter/st77xx/qp_st7735.c b/drivers/painter/st77xx/qp_st7735.c index 7ee5a6b562..1fd8f42186 100644 --- a/drivers/painter/st77xx/qp_st7735.c +++ b/drivers/painter/st77xx/qp_st7735.c @@ -1,5 +1,5 @@  // Copyright 2021 Paul Cotter (@gr1mr3aver) -// Copyright 2021 Nick Brassel (@tzarc) +// Copyright 2021-2023 Nick Brassel (@tzarc)  // Copyright 2022 David Hoelscher (@customMK)  // SPDX-License-Identifier: GPL-2.0-or-later @@ -134,6 +134,12 @@ painter_device_t qp_st7735_make_spi_device(uint16_t panel_width, uint16_t panel_              driver->spi_dc_reset_config.spi_config.mode            = spi_mode;              driver->spi_dc_reset_config.dc_pin                     = dc_pin;              driver->spi_dc_reset_config.reset_pin                  = reset_pin; + +            if (!qp_internal_register_device((painter_device_t)driver)) { +                memset(driver, 0, sizeof(tft_panel_dc_reset_painter_device_t)); +                return NULL; +            } +              return (painter_device_t)driver;          }      } diff --git a/drivers/painter/st77xx/qp_st7789.c b/drivers/painter/st77xx/qp_st7789.c index 9f474369d6..df43437733 100644 --- a/drivers/painter/st77xx/qp_st7789.c +++ b/drivers/painter/st77xx/qp_st7789.c @@ -1,5 +1,5 @@  // Copyright 2021 Paul Cotter (@gr1mr3aver) -// Copyright 2021 Nick Brassel (@tzarc) +// Copyright 2021-2023 Nick Brassel (@tzarc)  // SPDX-License-Identifier: GPL-2.0-or-later  #include "qp_internal.h" @@ -133,6 +133,12 @@ painter_device_t qp_st7789_make_spi_device(uint16_t panel_width, uint16_t panel_              driver->spi_dc_reset_config.spi_config.mode            = spi_mode;              driver->spi_dc_reset_config.dc_pin                     = dc_pin;              driver->spi_dc_reset_config.reset_pin                  = reset_pin; + +            if (!qp_internal_register_device((painter_device_t)driver)) { +                memset(driver, 0, sizeof(tft_panel_dc_reset_painter_device_t)); +                return NULL; +            } +              return (painter_device_t)driver;          }      } diff --git a/quantum/painter/qp.h b/quantum/painter/qp.h index 00f5d7931a..7222d3b413 100644 --- a/quantum/painter/qp.h +++ b/quantum/painter/qp.h @@ -1,4 +1,4 @@ -// Copyright 2021 Nick Brassel (@tzarc) +// Copyright 2021-2023 Nick Brassel (@tzarc)  // SPDX-License-Identifier: GPL-2.0-or-later  #pragma once @@ -11,6 +11,22 @@  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  // Quantum Painter global configurables (add to your keyboard's config.h) +#ifndef QUANTUM_PAINTER_DISPLAY_TIMEOUT +/** + * @def This controls the amount of time (in milliseconds) that all displays will remain on after the last user input. + *      If set to 0, the display will remain on indefinitely. + */ +#    define QUANTUM_PAINTER_DISPLAY_TIMEOUT 30000 +#endif // QUANTUM_PAINTER_DISPLAY_TIMEOUT + +#ifndef QUANTUM_PAINTER_TASK_THROTTLE +/** + * @def This controls the amount of time (in milliseconds) that the Quantum Painter internal task will wait between + *      each execution. + */ +#    define QUANTUM_PAINTER_TASK_THROTTLE 1 +#endif // QUANTUM_PAINTER_TASK_THROTTLE +  #ifndef QUANTUM_PAINTER_NUM_IMAGES  /**   * @def This controls the maximum number of images that Quantum Painter can load at any one time. Images can be loaded @@ -53,7 +69,7 @@   * @def This controls the maximum size of the pixel data buffer used for single blocks of transmission. Larger buffers   *      means more data is processed at one time, with less frequent transmissions, at the cost of RAM.   */ -#    define QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE 32 +#    define QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE 1024  #endif  #ifndef QUANTUM_PAINTER_SUPPORTS_256_PALETTE @@ -442,34 +458,50 @@ int16_t qp_drawtext_recolor(painter_device_t device, uint16_t x, uint16_t y, pai  #ifdef QUANTUM_PAINTER_RGB565_SURFACE_ENABLE  #    include "qp_rgb565_surface.h" +#else // QUANTUM_PAINTER_RGB565_SURFACE_ENABLE +#    define RGB565_SURFACE_NUM_DEVICES 0  #endif // QUANTUM_PAINTER_RGB565_SURFACE_ENABLE  #ifdef QUANTUM_PAINTER_ILI9163_ENABLE  #    include "qp_ili9163.h" +#else // QUANTUM_PAINTER_ILI9163_ENABLE +#    define ILI9163_NUM_DEVICES 0  #endif // QUANTUM_PAINTER_ILI9163_ENABLE  #ifdef QUANTUM_PAINTER_ILI9341_ENABLE  #    include "qp_ili9341.h" +#else // QUANTUM_PAINTER_ILI9341_ENABLE +#    define ILI9341_NUM_DEVICES 0  #endif // QUANTUM_PAINTER_ILI9341_ENABLE  #ifdef QUANTUM_PAINTER_ILI9488_ENABLE  #    include "qp_ili9488.h" +#else // QUANTUM_PAINTER_ILI9488_ENABLE +#    define ILI9488_NUM_DEVICES 0  #endif // QUANTUM_PAINTER_ILI9488_ENABLE  #ifdef QUANTUM_PAINTER_ST7789_ENABLE  #    include "qp_st7789.h" +#else // QUANTUM_PAINTER_ST7789_ENABLE +#    define ST7789_NUM_DEVICES 0  #endif // QUANTUM_PAINTER_ST7789_ENABLE  #ifdef QUANTUM_PAINTER_ST7735_ENABLE  #    include "qp_st7735.h" +#else // QUANTUM_PAINTER_ST7735_ENABLE +#    define ST7735_NUM_DEVICES 0  #endif // QUANTUM_PAINTER_ST7735_ENABLE  #ifdef QUANTUM_PAINTER_GC9A01_ENABLE  #    include "qp_gc9a01.h" +#else // QUANTUM_PAINTER_GC9A01_ENABLE +#    define GC9A01_NUM_DEVICES 0  #endif // QUANTUM_PAINTER_GC9A01_ENABLE  #ifdef QUANTUM_PAINTER_SSD1351_ENABLE  #    include "qp_ssd1351.h" +#else // QUANTUM_PAINTER_SSD1351_ENABLE +#    define SSD1351_NUM_DEVICES 0  #endif // QUANTUM_PAINTER_SSD1351_ENABLE  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/quantum/painter/qp_draw_image.c b/quantum/painter/qp_draw_image.c index fa80617242..e722f3cf02 100644 --- a/quantum/painter/qp_draw_image.c +++ b/quantum/painter/qp_draw_image.c @@ -1,4 +1,4 @@ -// Copyright 2021 Nick Brassel (@tzarc) +// Copyright 2021-2023 Nick Brassel (@tzarc)  // SPDX-License-Identifier: GPL-2.0-or-later  #include "qp_internal.h" @@ -414,15 +414,3 @@ void qp_internal_animation_tick(void) {      static uint32_t last_anim_exec = 0;      deferred_exec_advanced_task(animation_executors, QUANTUM_PAINTER_CONCURRENT_ANIMATIONS, &last_anim_exec);  } - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter Core API: qp_internal_task - -void qp_internal_task(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 -} 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]); +        } +    } +} diff --git a/quantum/painter/qp_internal_driver.h b/quantum/painter/qp_internal_driver.h index 82a0178a73..c976ff9db7 100644 --- a/quantum/painter/qp_internal_driver.h +++ b/quantum/painter/qp_internal_driver.h @@ -1,4 +1,4 @@ -// Copyright 2021 Nick Brassel (@tzarc) +// Copyright 2021-2023 Nick Brassel (@tzarc)  // SPDX-License-Identifier: GPL-2.0-or-later  #pragma once @@ -82,3 +82,8 @@ struct painter_driver_t {      // Comms config pointer -- needs to point to an appropriate comms config if the comms driver requires it.      void *comms_config;  }; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Device internals + +bool qp_internal_register_device(painter_device_t driver); diff --git a/quantum/painter/rules.mk b/quantum/painter/rules.mk index 199e406dd6..7752936cbd 100644 --- a/quantum/painter/rules.mk +++ b/quantum/painter/rules.mk @@ -24,6 +24,7 @@ SRC += \      $(QUANTUM_DIR)/unicode/utf8.c \      $(QUANTUM_DIR)/color.c \      $(QUANTUM_DIR)/painter/qp.c \ +    $(QUANTUM_DIR)/painter/qp_internal.c \      $(QUANTUM_DIR)/painter/qp_stream.c \      $(QUANTUM_DIR)/painter/qgf.c \      $(QUANTUM_DIR)/painter/qff.c \ | 
