oled_display.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /* Copyright 2020 yushakobo
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include QMK_KEYBOARD_H
  19. #ifdef SSD1306OLED
  20. #include "ssd1306.h"
  21. #endif
  22. // Each layer gets a name for readability, which is then used in the keymap matrix below.
  23. // The underscores don't mean anything - you can have a layer called STUFF or any other name.
  24. // Layer names don't all need to be of the same length, obviously, and you can also skip them
  25. // entirely and just use numbers.
  26. enum layer_number {
  27. _QWERTY = 0,
  28. _COLEMAK,
  29. _DVORAK,
  30. _LOWER,
  31. _RAISE,
  32. _ADJUST
  33. };
  34. //SSD1306 OLED update loop, make sure to add #define SSD1306OLED in config.h
  35. #if defined(SSD1306OLED) || defined(OLED_DRIVER_ENABLE)
  36. # if defined(OLED_DRIVER_ENABLE)
  37. oled_rotation_t oled_init_user(oled_rotation_t rotation) {
  38. if (is_keyboard_master()) {
  39. return OLED_ROTATION_0;
  40. } else {
  41. return OLED_ROTATION_180;
  42. }
  43. }
  44. # else
  45. # define oled_write(data,flag) matrix_write(matrix, data)
  46. # define oled_write_P(data,flag) matrix_write_P(matrix, data)
  47. # endif
  48. # ifdef SSD1306OLED
  49. void matrix_scan_user(void) {
  50. iota_gfx_task(); // this is what updates the display continuously
  51. }
  52. void matrix_update(struct CharacterMatrix *dest,
  53. const struct CharacterMatrix *source) {
  54. if (memcmp(dest->display, source->display, sizeof(dest->display))) {
  55. memcpy(dest->display, source->display, sizeof(dest->display));
  56. dest->dirty = true;
  57. }
  58. }
  59. # endif
  60. //assign the right code to your layers for OLED display
  61. #define L_BASE 0
  62. #define L_LOWER (1<<_LOWER)
  63. #define L_RAISE (1<<_RAISE)
  64. #define L_ADJUST (1<<_ADJUST)
  65. #define L_ADJUST_TRI (L_ADJUST|L_RAISE|L_LOWER)
  66. # ifdef SSD1306OLED
  67. static void render_logo(struct CharacterMatrix *matrix) {
  68. # else
  69. static void render_logo(void) {
  70. # endif
  71. static const char helix_logo[] PROGMEM ={
  72. 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,
  73. 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,
  74. 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,
  75. 0};
  76. oled_write_P(helix_logo, false);
  77. }
  78. # ifdef SSD1306OLED
  79. static void render_rgbled_status(bool full, struct CharacterMatrix *matrix) {
  80. # else
  81. static void render_rgbled_status(bool full) {
  82. # endif
  83. # ifdef RGBLIGHT_ENABLE
  84. char buf[30];
  85. if (RGBLIGHT_MODES > 1 && rgblight_is_enabled()) {
  86. if (full) {
  87. snprintf(buf, sizeof(buf), " LED %2d: %d,%d,%d ",
  88. rgblight_get_mode(),
  89. rgblight_get_hue()/RGBLIGHT_HUE_STEP,
  90. rgblight_get_sat()/RGBLIGHT_SAT_STEP,
  91. rgblight_get_val()/RGBLIGHT_VAL_STEP);
  92. } else {
  93. snprintf(buf, sizeof(buf), "[%2d] ", rgblight_get_mode());
  94. }
  95. oled_write(buf, false);
  96. }
  97. # endif
  98. }
  99. # ifdef SSD1306OLED
  100. static void render_layer_status(struct CharacterMatrix *matrix) {
  101. # else
  102. static void render_layer_status(void) {
  103. # endif
  104. // Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
  105. char buf[10];
  106. oled_write_P(PSTR("Layer: "), false);
  107. switch (layer_state) {
  108. case L_BASE:
  109. oled_write_P(PSTR("Default"), false);
  110. break;
  111. case L_RAISE:
  112. oled_write_P(PSTR("Raise"), false);
  113. break;
  114. case L_LOWER:
  115. oled_write_P(PSTR("Lower"), false);
  116. break;
  117. case L_ADJUST:
  118. case L_ADJUST_TRI:
  119. oled_write_P(PSTR("Adjust"), false);
  120. break;
  121. default:
  122. oled_write_P(PSTR("Undef-"), false);
  123. snprintf(buf,sizeof(buf), "%ld", layer_state);
  124. oled_write(buf, false);
  125. }
  126. oled_write_P(PSTR("\n"), false);
  127. }
  128. # ifdef SSD1306OLED
  129. void render_status(struct CharacterMatrix *matrix) {
  130. # else
  131. void render_status(void) {
  132. # endif
  133. // Render to mode icon
  134. static const char os_logo[][2][3] PROGMEM = {{{0x95,0x96,0},{0xb5,0xb6,0}},{{0x97,0x98,0},{0xb7,0xb8,0}}};
  135. if (is_mac_mode()) {
  136. oled_write_P(os_logo[0][0], false);
  137. oled_write_P(PSTR("\n"), false);
  138. oled_write_P(os_logo[0][1], false);
  139. } else {
  140. oled_write_P(os_logo[1][0], false);
  141. oled_write_P(PSTR("\n"), false);
  142. oled_write_P(os_logo[1][1], false);
  143. }
  144. oled_write_P(PSTR(" "), false);
  145. # ifdef SSD1306OLED
  146. render_layer_status(matrix);
  147. # else
  148. render_layer_status();
  149. # endif
  150. // Host Keyboard LED Status
  151. led_t led_state = host_keyboard_led_state();
  152. oled_write_P(led_state.num_lock ? PSTR("NUMLOCK") : PSTR(" "), false);
  153. oled_write_P(led_state.caps_lock ? PSTR("CAPS") : PSTR(" "), false);
  154. oled_write_P(led_state.scroll_lock ? PSTR("SCLK") : PSTR(" "), false);
  155. oled_write_P(PSTR("\n"), false);
  156. # ifdef SSD1306OLED
  157. render_rgbled_status(true, matrix);
  158. # else
  159. render_rgbled_status(true);
  160. oled_write_P(PSTR("\n"), false);
  161. # endif
  162. }
  163. # ifdef SSD1306OLED
  164. # if OLED_UPDATE_INTERVAL > 0
  165. uint16_t oled_update_timeout;
  166. # endif
  167. void iota_gfx_task_user(void) {
  168. struct CharacterMatrix matrix;
  169. # if DEBUG_TO_SCREEN
  170. if (debug_enable) {
  171. return;
  172. }
  173. # endif
  174. #if OLED_UPDATE_INTERVAL > 0
  175. if (timer_elapsed(oled_update_timeout) < OLED_UPDATE_INTERVAL) {
  176. return;
  177. }
  178. oled_update_timeout = timer_read();
  179. #endif
  180. matrix_clear(&matrix);
  181. if (is_keyboard_master()) {
  182. render_status(&matrix);
  183. } else {
  184. render_logo(&matrix);
  185. render_rgbled_status(false, &matrix);
  186. render_layer_status(&matrix);
  187. }
  188. matrix_update(&display, &matrix);
  189. }
  190. # else
  191. void oled_task_user(void) {
  192. # if DEBUG_TO_SCREEN
  193. if (debug_enable) {
  194. return;
  195. }
  196. # endif
  197. if (is_keyboard_master()) {
  198. render_status();
  199. } else {
  200. render_logo();
  201. render_rgbled_status(false);
  202. render_layer_status();
  203. }
  204. }
  205. # endif
  206. #endif