logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

ui.c (5779B)


  1. // Copyright 2018-2022 Nick Brassel (@tzarc)
  2. // SPDX-License-Identifier: GPL-3.0-or-later
  3. #include <stdio.h>
  4. #include QMK_KEYBOARD_H
  5. #include "analog.h"
  6. #include "qp.h"
  7. #include "qp_ssd1351.h"
  8. #define NUM_ADC_READS 32
  9. #include "graphics/ghoul-logo.qgf.c"
  10. #include "graphics/ghoul-name.qgf.c"
  11. #include "graphics/lock-caps.qgf.c"
  12. #include "graphics/lock-num.qgf.c"
  13. #include "graphics/lock-scrl.qgf.c"
  14. #include "graphics/thintel15.qff.c"
  15. static painter_device_t oled;
  16. static painter_image_handle_t logo;
  17. static painter_image_handle_t name;
  18. static painter_font_handle_t font;
  19. static painter_image_handle_t lock_caps;
  20. static painter_image_handle_t lock_num;
  21. static painter_image_handle_t lock_scrl;
  22. void ui_init(void) {
  23. oled = qp_ssd1351_make_spi_device(128, 128, OLED_CS_PIN, OLED_DC_PIN, OLED_RST_PIN, 8, 0);
  24. logo = qp_load_image_mem(gfx_ghoul_logo);
  25. name = qp_load_image_mem(gfx_ghoul_name);
  26. font = qp_load_font_mem(font_thintel15);
  27. lock_caps = qp_load_image_mem(gfx_lock_caps);
  28. lock_num = qp_load_image_mem(gfx_lock_num);
  29. lock_scrl = qp_load_image_mem(gfx_lock_scrl);
  30. qp_init(oled, QP_ROTATION_90);
  31. qp_rect(oled, 0, 0, 127, 127, 0, 0, 0, true);
  32. qp_flush(oled);
  33. }
  34. void ui_task(void) {
  35. bool hue_redraw = false;
  36. static uint16_t last_hue = 0xFFFF;
  37. uint8_t curr_hue = rgblight_get_hue();
  38. if (last_hue != curr_hue) {
  39. last_hue = curr_hue;
  40. hue_redraw = true;
  41. }
  42. if (hue_redraw) {
  43. qp_drawimage_recolor(oled, 0, 64 - (name->height / 2), name, curr_hue, 255, 255, curr_hue, 255, 0);
  44. qp_drawimage_recolor(oled, 127 - logo->width, 0, logo, curr_hue, 255, 255, curr_hue, 255, 0);
  45. }
  46. static led_t last_led_state = {0};
  47. if (hue_redraw || last_led_state.raw != host_keyboard_led_state().raw) {
  48. last_led_state.raw = host_keyboard_led_state().raw;
  49. qp_drawimage_recolor(oled, lock_caps->width * 0, 0, lock_caps, curr_hue, 255, last_led_state.caps_lock ? 255 : 32, curr_hue, 255, 0);
  50. qp_drawimage_recolor(oled, lock_caps->width * 1, 0, lock_num, curr_hue, 255, last_led_state.num_lock ? 255 : 32, curr_hue, 255, 0);
  51. qp_drawimage_recolor(oled, lock_caps->width * 2, 0, lock_scrl, curr_hue, 255, last_led_state.scroll_lock ? 255 : 32, curr_hue, 255, 0);
  52. qp_rect(oled, lock_caps->width * 0 + 1, lock_caps->height + 2, lock_caps->width * 1 - 1, lock_caps->height + 3, curr_hue, 255, last_led_state.caps_lock ? 255 : 0, true);
  53. qp_rect(oled, lock_caps->width * 1 + 1, lock_caps->height + 2, lock_caps->width * 2 - 1, lock_caps->height + 3, curr_hue, 255, last_led_state.num_lock ? 255 : 0, true);
  54. qp_rect(oled, lock_caps->width * 2 + 1, lock_caps->height + 2, lock_caps->width * 3 - 1, lock_caps->height + 3, curr_hue, 255, last_led_state.scroll_lock ? 255 : 0, true);
  55. }
  56. #if HAL_USE_ADC
  57. static int16_t current_reads[NUM_ADC_READS] = {0};
  58. static int16_t voltage_reads[NUM_ADC_READS] = {0};
  59. static int write_offset = 0;
  60. static uint32_t last_read = 0;
  61. if (timer_elapsed32(last_read) >= 1) {
  62. // Perform the reads
  63. int16_t current = analogReadPin(ADC_CURRENT_PIN);
  64. int16_t voltage = analogReadPin(ADC_VOLTAGE_PIN);
  65. int16_t current_ma = (int16_t)(((3300 * (int32_t)current) / ADC_SATURATION));
  66. int16_t voltage_mv = (int16_t)((2 * (3300 * (int32_t)voltage)) / ADC_SATURATION);
  67. // Duplicate the first read so that averages work
  68. if (last_read == 0) {
  69. for (int i = 0; i < NUM_ADC_READS; ++i) {
  70. current_reads[i] = current_ma;
  71. voltage_reads[i] = voltage_mv;
  72. }
  73. }
  74. // Dump in the current value
  75. current_reads[write_offset] = current_ma;
  76. voltage_reads[write_offset] = voltage_mv;
  77. write_offset = (write_offset + 1) % NUM_ADC_READS;
  78. static int counter = 0;
  79. counter = (counter + 1) % 2500;
  80. if (counter == 0) {
  81. dprintf("Current: %dmA (%d) -- Voltage: %dmV (%d)\n", (int)current_ma, (int)current, (int)voltage_mv, (int)voltage);
  82. }
  83. last_read = timer_read32();
  84. }
  85. static uint32_t last_draw = 0;
  86. if (hue_redraw || timer_elapsed32(last_draw) >= 250) {
  87. // Accumulate
  88. int32_t total_current_ma = 0;
  89. int32_t total_voltage_mv = 0;
  90. for (int i = 0; i < NUM_ADC_READS; ++i) {
  91. total_current_ma += current_reads[i];
  92. total_voltage_mv += voltage_reads[i];
  93. }
  94. // Get the averages
  95. int16_t avg_current_ma = (int16_t)(total_current_ma / NUM_ADC_READS);
  96. int16_t avg_voltage_mv = (int16_t)(total_voltage_mv / NUM_ADC_READS);
  97. char buf[32] = {0};
  98. sprintf(buf, "Current: %dmA", avg_current_ma);
  99. static int16_t maxlen_curr = 0;
  100. int16_t len = qp_drawtext_recolor(oled, 0, 127 - (font->line_height * 2), font, buf, 0, 0, 32, 0, 0, 0);
  101. if (len < maxlen_curr) {
  102. qp_rect(oled, len, 127 - (font->line_height * 2), maxlen_curr, 127 - (font->line_height * 1), 0, 0, 0, true);
  103. } else if (len > maxlen_curr) {
  104. maxlen_curr = len;
  105. }
  106. static int16_t maxlen_volt = 0;
  107. sprintf(buf, "Voltage: %dmV", avg_voltage_mv);
  108. len = qp_drawtext_recolor(oled, 0, 127 - (font->line_height * 1), font, buf, 0, 0, 32, 0, 0, 0);
  109. if (len < maxlen_volt) {
  110. qp_rect(oled, len, 127 - (font->line_height * 1), maxlen_volt, 127 - (font->line_height * 0), 0, 0, 0, true);
  111. } else if (len > maxlen_volt) {
  112. maxlen_volt = len;
  113. }
  114. qp_flush(oled);
  115. last_draw = timer_read32();
  116. }
  117. #endif // HAL_USE_ADC
  118. }