qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

display.c (6379B)


      1 // Copyright 2023 Dasky (@daskygit)
      2 // SPDX-License-Identifier: GPL-2.0-or-later
      3 
      4 #include "display.h"
      5 #include "graphics/splash.qgf.h"
      6 #include "graphics/reverb.qgf.h"
      7 #include "graphics/robotomono20.qff.h"
      8 #include <stdio.h>
      9 #include <math.h>
     10 
     11 static painter_image_handle_t reverb_logo;
     12 static painter_image_handle_t splash_image;
     13 static deferred_token         display_task_token;
     14 static uint32_t               key_pressed_count = 0;
     15 
     16 static uint8_t reverb_surface_fb[SURFACE_REQUIRED_BUFFER_BYTE_SIZE(240, 240, 16)];
     17 
     18 painter_device_t      reverb_surface;
     19 painter_device_t      reverb_display;
     20 painter_font_handle_t roboto_font;
     21 
     22 uint32_t display_task_callback(uint32_t trigger_time, void *cb_arg) {
     23     display_task_kb();
     24     return 100;
     25 }
     26 
     27 void display_init_kb(void) {
     28     reverb_display = qp_gc9a01_make_spi_device(240, 240, DISPLAY_CS, DISPLAY_DC, DISPLAY_RST, 2, 0); // always init display
     29     qp_init(reverb_display, QP_ROTATION_0);
     30     roboto_font    = qp_load_font_mem(font_robotomono20);
     31     reverb_surface = qp_make_rgb565_surface(240, 240, reverb_surface_fb);
     32     qp_init(reverb_surface, QP_ROTATION_0);
     33     if (!display_init_user()) {
     34         return;
     35     }
     36     splash_image = qp_load_image_mem(gfx_splash);
     37     reverb_logo  = qp_load_image_mem(gfx_reverb);
     38     qp_drawimage(reverb_display, 0, 0, splash_image);
     39     qp_flush(reverb_display);
     40     qp_close_image(splash_image);
     41     display_task_token = defer_exec(2000, display_task_callback, NULL);
     42 }
     43 
     44 __attribute__((weak)) bool display_init_user(void) {
     45     return true;
     46 }
     47 
     48 void display_task_kb(void) {
     49     if (!display_task_user()) {
     50         return;
     51     }
     52     static bool     first_draw             = true;
     53     static uint32_t last_timer             = 0;
     54     static uint32_t last_wpm               = UINT32_MAX;
     55     static uint32_t last_scan_rate         = 0;
     56     static uint32_t last_key_pressed_count = UINT32_MAX;
     57     static uint8_t  last_hue               = 0;
     58     static uint8_t  last_sat               = 0;
     59     static uint8_t  last_val               = 0;
     60     bool            rgb_redraw             = false;
     61 
     62     if (first_draw) {
     63         qp_rect(reverb_display, 0, 0, 239, 239, 0, 0, 0, true);
     64         first_draw = false;
     65     }
     66 
     67     char buffer[64] = {0};
     68 
     69     if (last_hue != rgb_matrix_get_hue() || last_sat != rgb_matrix_get_sat() || last_val != rgb_matrix_get_val()) {
     70         last_hue = rgb_matrix_get_hue();
     71         last_sat = rgb_matrix_get_sat();
     72         last_val = rgb_matrix_get_val();
     73         qp_drawimage_recolor(reverb_surface, 60, 40, reverb_logo, rgb_matrix_get_hue(), rgb_matrix_get_sat(), MAX(rgb_matrix_get_val(), 128), 0, 0, 0);
     74         rgb_redraw = true;
     75     }
     76 
     77     if (rgb_redraw || last_scan_rate != get_matrix_scan_rate()) {
     78         snprintf(buffer, sizeof(buffer), "Scan Rate %ld", get_matrix_scan_rate());
     79         int16_t width = qp_textwidth(roboto_font, buffer);
     80         qp_line(reverb_surface, 17, 101, 220, 101, rgb_matrix_get_hue(), rgb_matrix_get_sat(), MAX(rgb_matrix_get_val(), 128));
     81         qp_rect(reverb_surface, 16, 125 - roboto_font->line_height, 221, 125, 0, 0, 0, true);
     82         qp_drawtext_recolor(reverb_surface, (120 - (width / 2)), (125 - roboto_font->line_height), roboto_font, buffer, rgb_matrix_get_hue(), rgb_matrix_get_sat(), MAX(rgb_matrix_get_val(), 128), 0, 0, 0);
     83         qp_line(reverb_surface, 16, 126, 221, 126, rgb_matrix_get_hue(), rgb_matrix_get_sat(), MAX(rgb_matrix_get_val(), 128));
     84         last_scan_rate = get_matrix_scan_rate();
     85     }
     86     if (rgb_redraw || last_key_pressed_count != key_pressed_count) {
     87         snprintf(buffer, sizeof(buffer), "Keys Pressed");
     88         int16_t width = qp_textwidth(roboto_font, buffer);
     89         qp_rect(reverb_surface, 30, 150 - roboto_font->line_height, 209, 150, 0, 0, 0, true);
     90         qp_drawtext_recolor(reverb_surface, (120 - (width / 2)), (150 - roboto_font->line_height), roboto_font, buffer, rgb_matrix_get_hue(), rgb_matrix_get_sat(), MAX(rgb_matrix_get_val(), 128), 0, 0, 0);
     91         snprintf(buffer, sizeof(buffer), "%ld", key_pressed_count);
     92         width = qp_textwidth(roboto_font, buffer);
     93         qp_rect(reverb_surface, 30, 172 - roboto_font->line_height, 173, 172, 0, 0, 0, true);
     94         qp_drawtext_recolor(reverb_surface, (120 - (width / 2)), (172 - roboto_font->line_height), roboto_font, buffer, rgb_matrix_get_hue(), rgb_matrix_get_sat(), MAX(rgb_matrix_get_val(), 128), 0, 0, 0);
     95         qp_line(reverb_surface, 30, 173, 209, 173, rgb_matrix_get_hue(), rgb_matrix_get_sat(), MAX(rgb_matrix_get_val(), 128));
     96         last_key_pressed_count = key_pressed_count;
     97     }
     98     if (rgb_redraw || last_wpm != get_current_wpm()) {
     99         snprintf(buffer, sizeof(buffer), "WPM %d", get_current_wpm());
    100         int16_t width = qp_textwidth(roboto_font, buffer);
    101         qp_rect(reverb_surface, 56, 200 - roboto_font->line_height, 184, 200, 0, 0, 0, true);
    102         qp_drawtext_recolor(reverb_surface, (120 - (width / 2)), (200 - roboto_font->line_height), roboto_font, buffer, rgb_matrix_get_hue(), rgb_matrix_get_sat(), MAX(rgb_matrix_get_val(), 128), 0, 0, 0);
    103         qp_line(reverb_surface, 56, 201, 184, 201, rgb_matrix_get_hue(), rgb_matrix_get_sat(), MAX(rgb_matrix_get_val(), 128));
    104         last_wpm = get_current_wpm();
    105     }
    106 
    107     if (rgb_redraw || timer_elapsed(last_timer) >= 1000) {
    108         static uint8_t seconds = 0;
    109         static uint8_t x       = 0;
    110         static uint8_t y       = 0;
    111         if (x && y) {
    112             qp_circle(reverb_surface, x, y, 4, 0, 0, 0, true);
    113         }
    114         double radians = 0.10471975511966 * seconds;
    115         x              = (110 * cos(radians)) + 119;
    116         y              = (110 * sin(radians)) + 119;
    117         qp_circle(reverb_surface, x, y, 4, rgb_matrix_get_hue(), rgb_matrix_get_sat(), MAX(rgb_matrix_get_val(), 128), true);
    118         qp_circle(reverb_surface, 119, 119, 105, rgb_matrix_get_hue(), rgb_matrix_get_sat(), MAX(rgb_matrix_get_val(), 128), false);
    119         if (seconds == 59) {
    120             seconds = 0;
    121         } else if (timer_elapsed(last_timer) >= 1000) {
    122             last_timer = timer_read32();
    123             seconds++;
    124         }
    125     }
    126 
    127     qp_surface_draw(reverb_surface, reverb_display, 0, 0, rgb_redraw);
    128 }
    129 
    130 __attribute__((weak)) bool display_task_user(void) {
    131     return true;
    132 }
    133 
    134 void display_key_counter(void) {
    135     if (key_pressed_count == UINT32_MAX) {
    136         key_pressed_count = 0;
    137     }
    138     key_pressed_count++;
    139 }