logo

qmk_firmware

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

puckbuddy.c (10680B)


  1. // Copyright 2022 Kyle McCreery (@kylemccreery)
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "puckbuddy.h"
  4. #ifndef GLIDEPOINT_DPI_OPTIONS
  5. # define GLIDEPOINT_DPI_OPTIONS \
  6. { 400, 800, 1200, 1600, 2000, 2400, 2800, 3200, 3600, 4000 }
  7. # ifndef GLIDEPOINT_DPI_DEFAULT
  8. # define GLIDEPOINT_DPI_DEFAULT 1
  9. # endif
  10. #endif
  11. #ifndef GLIDEPOINT_DPI_DEFAULT
  12. # define GLIDEPOINT_DPI_DEFAULT 1
  13. #endif
  14. keyboard_config_t keyboard_config;
  15. uint16_t dpi_array[] = GLIDEPOINT_DPI_OPTIONS;
  16. #define DPI_OPTION_SIZE ARRAY_SIZE(dpi_array)
  17. void board_init(void) {
  18. // B9 is configured as I2C1_SDA in the board file; that function must be
  19. // disabled before using B7 as I2C1_SDA.
  20. gpio_set_pin_input_high(B9);
  21. }
  22. #ifdef DYNAMIC_TAPPING_TERM_ENABLE
  23. void tap_modify(int change_value, bool tap_status) {
  24. if (keyboard_config.dt_term_config < 0) {
  25. keyboard_config.dt_term_config *= -1;
  26. }
  27. keyboard_config.dt_term_config += change_value;
  28. if (tap_status == false ) {
  29. keyboard_config.dt_term_config *= -1;
  30. g_tapping_term = 0;
  31. } else {
  32. g_tapping_term = keyboard_config.dt_term_config;
  33. }
  34. eeconfig_update_kb(keyboard_config.raw);
  35. }
  36. void tap_toggle(void) {
  37. keyboard_config.dt_term_config *= -1;
  38. if (keyboard_config.dt_term_config > 0) {
  39. g_tapping_term = keyboard_config.dt_term_config;
  40. } else {
  41. g_tapping_term = 0;
  42. }
  43. eeconfig_update_kb(keyboard_config.raw);
  44. }
  45. #endif
  46. #ifdef DIP_SWITCH_ENABLE
  47. bool dip_switch_update_kb(uint8_t index, bool active) {
  48. if (!dip_switch_update_user(index, active)) { return false; }
  49. switch (index) {
  50. case 0:
  51. if(active) { tap_code(KC_CAPS_LOCK); }
  52. break;
  53. break;
  54. }
  55. return true;
  56. }
  57. #endif
  58. #ifdef ENCODER_ENABLE
  59. bool encoder_update_kb(uint8_t index, bool clockwise) {
  60. if (!encoder_update_user(index, clockwise)) { return false; }
  61. switch (index) {
  62. case 0:
  63. if (clockwise) {
  64. tap_code(KC_VOLU);
  65. } else {
  66. tap_code(KC_VOLD);
  67. }
  68. break;
  69. case 1:
  70. if (clockwise) {
  71. tap_code(KC_PGUP);
  72. } else {
  73. tap_code(KC_PGDN);
  74. }
  75. break;
  76. }
  77. return true;
  78. }
  79. #endif
  80. #ifdef OLED_ENABLE // OLED Functionality
  81. oled_rotation_t oled_init_user(oled_rotation_t rotation) {
  82. return OLED_ROTATION_180; // flips the display 180 degrees
  83. }
  84. bool clear_screen = true; // used to manage singular screen clears to prevent display glitch
  85. bool clear_screen_art = true; // used to manage singular screen clears to prevent display glitch
  86. static void render_name(void) { // Render Puckbuddy "Get Puck'd" text
  87. static const char PROGMEM name_1[] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0xB6, 0xB6, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x00};
  88. static const char PROGMEM name_2[] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xB6, 0xB6, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0x00};
  89. static const char PROGMEM name_3[] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xB6, 0xB6, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0x00};
  90. oled_set_cursor(0,0);
  91. oled_write_P(name_1, false);
  92. oled_set_cursor(0,1);
  93. oled_write_P(name_2, false);
  94. oled_set_cursor(0,2);
  95. oled_write_P(name_3, false);
  96. }
  97. static void render_logo(void) { // Render MechWild "MW" Logo
  98. static const char PROGMEM logo_1[] = {0x97, 0x98, 0x99, 0x9A,0x00};
  99. static const char PROGMEM logo_2[] = {0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0x00};
  100. static const char PROGMEM logo_3[] = {0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xB6, 0x00};
  101. static const char PROGMEM logo_4[] = {0xB6, 0xB6, 0xB6, 0x9B, 0x9C, 0x9D, 0x9E, 0x00};
  102. oled_set_cursor(0,0);
  103. oled_write_P(logo_1, false);
  104. oled_set_cursor(0,1);
  105. oled_write_P(logo_2, false);
  106. oled_set_cursor(0,2);
  107. oled_write_P(logo_3, false);
  108. oled_set_cursor(0,3);
  109. oled_write_P(logo_4, false);
  110. }
  111. bool oled_task_kb(void) {
  112. if(!oled_task_user()) {
  113. return false;
  114. }
  115. led_t led_state = host_keyboard_led_state();
  116. if ( !led_state.num_lock && !led_state.caps_lock && !led_state.scroll_lock && get_highest_layer(layer_state) == 0 ) {
  117. if (clear_screen_art == true) {
  118. oled_clear();
  119. oled_render();
  120. clear_screen_art = false;
  121. }
  122. render_name();
  123. oled_set_cursor(0,3);
  124. #ifdef POINTING_DEVICE_ENABLE
  125. oled_write_P(PSTR(" DPI:"), false);
  126. oled_write(get_u16_str(dpi_array[keyboard_config.dpi_config], ' '), false);
  127. #endif
  128. #ifdef DYNAMIC_TAPPING_TERM_ENABLE // only display tap info if it is being configured dynamically
  129. oled_write_P(PSTR(" TAP:"), false);
  130. if (keyboard_config.dt_term_config < 0) {
  131. oled_write_P(PSTR("Off "), false);
  132. } else {
  133. oled_write(get_u16_str(g_tapping_term, ' '), false);
  134. }
  135. #endif
  136. clear_screen = true;
  137. } else {
  138. if (clear_screen == true) {
  139. oled_clear();
  140. oled_render();
  141. clear_screen = false;
  142. }
  143. render_logo();
  144. oled_set_cursor(8,1);
  145. switch (get_highest_layer(layer_state)) {
  146. case 0:
  147. oled_write_P(PSTR("Layer 0"), false);
  148. break;
  149. case 1:
  150. oled_write_P(PSTR("Layer 1"), false);
  151. break;
  152. case 2:
  153. oled_write_P(PSTR("Layer 2"), false);
  154. break;
  155. case 3:
  156. oled_write_P(PSTR("Layer 3"), false);
  157. break;
  158. default:
  159. oled_write_P(PSTR("Layer ?"), false); // Should never display, here as a catchall
  160. }
  161. led_t led_state = host_keyboard_led_state();
  162. oled_set_cursor(8,0);
  163. oled_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR(" "), false);
  164. oled_write_P(led_state.caps_lock ? PSTR("CAP ") : PSTR(" "), false);
  165. oled_write_P(led_state.scroll_lock ? PSTR("SCR") : PSTR(" "), false);
  166. #ifdef POINTING_DEVICE_ENABLE
  167. oled_set_cursor(8,2);
  168. oled_write_P(PSTR("DPI:"), false);
  169. oled_write(get_u16_str(dpi_array[keyboard_config.dpi_config], ' '), false);
  170. #endif
  171. #ifdef DYNAMIC_TAPPING_TERM_ENABLE // only display tap info if it is being configured dynamically
  172. oled_set_cursor(8,3);
  173. oled_write_P(PSTR("TAP:"), false);
  174. if (keyboard_config.dt_term_config < 0) {
  175. oled_write_P(PSTR("Off "), false);
  176. } else {
  177. oled_write(get_u16_str(g_tapping_term, ' '), false);
  178. }
  179. #endif
  180. clear_screen_art = true;
  181. }
  182. return true;
  183. }
  184. #endif
  185. bool process_record_kb(uint16_t keycode, keyrecord_t* record) {
  186. switch(keycode) {
  187. #ifdef POINTING_DEVICE_ENABLE
  188. case DPI_UP:
  189. if (record->event.pressed) {
  190. keyboard_config.dpi_config = (keyboard_config.dpi_config + 1) % DPI_OPTION_SIZE;
  191. eeconfig_update_kb(keyboard_config.raw);
  192. pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]);
  193. }
  194. return false;
  195. case DPI_DN:
  196. if (record->event.pressed) {
  197. if (keyboard_config.dpi_config > 0) {
  198. keyboard_config.dpi_config = (keyboard_config.dpi_config - 1) % DPI_OPTION_SIZE;
  199. } else {
  200. keyboard_config.dpi_config = DPI_OPTION_SIZE - 1;
  201. }
  202. eeconfig_update_kb(keyboard_config.raw);
  203. pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]);
  204. }
  205. return false;
  206. case DPI_FINE:
  207. if (record->event.pressed) {
  208. pointing_device_set_cpi(dpi_array[0]);
  209. } else {
  210. pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]);
  211. }
  212. return false;
  213. #endif
  214. #ifdef DYNAMIC_TAPPING_TERM_ENABLE // only include tap info keycodes if it is being configured dynamically
  215. case TAP_UP:
  216. if (record->event.pressed) {
  217. tap_modify(DYNAMIC_TAPPING_TERM_INCREMENT, true);
  218. }
  219. return false;
  220. case TAP_DN:
  221. if (record->event.pressed) {
  222. if (keyboard_config.dt_term_config > 0) {
  223. tap_modify(-1 * DYNAMIC_TAPPING_TERM_INCREMENT, true);
  224. }
  225. }
  226. return false;
  227. case TAP_ON:
  228. if (record->event.pressed) {
  229. tap_modify(0, true);
  230. }
  231. return false;
  232. case TAP_OFF:
  233. if (record->event.pressed) {
  234. tap_modify(0, false);
  235. }
  236. return false;
  237. case TAP_TOG:
  238. if (record->event.pressed) {
  239. tap_toggle();
  240. }
  241. return false;
  242. #endif
  243. }
  244. return process_record_user(keycode, record);
  245. }
  246. void pointing_device_init_kb(void) {
  247. #ifdef POINTING_DEVICE_ENABLE
  248. pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]);
  249. #endif
  250. }
  251. void eeconfig_init_kb(void) {
  252. #ifdef POINTING_DEVICE_ENABLE
  253. keyboard_config.dpi_config = GLIDEPOINT_DPI_DEFAULT;
  254. #endif
  255. #ifdef DYNAMIC_TAPPING_TERM_ENABLE // only set tap term from eeprom if it is being configured dynamically
  256. keyboard_config.dt_term_config = TAPPING_TERM;
  257. #endif
  258. eeconfig_update_kb(keyboard_config.raw);
  259. eeconfig_init_user();
  260. }
  261. void matrix_init_kb(void) {
  262. // is safe to just read DPI setting since matrix init
  263. // comes before pointing device init.
  264. keyboard_config.raw = eeconfig_read_kb();
  265. #ifdef POINTING_DEVICE_ENABLE
  266. if (keyboard_config.dpi_config > DPI_OPTION_SIZE) {
  267. eeconfig_init_kb();
  268. }
  269. #endif
  270. matrix_init_user();
  271. }
  272. void keyboard_post_init_kb(void) {
  273. #ifdef POINTING_DEVICE_ENABLE
  274. pointing_device_set_cpi(dpi_array[keyboard_config.dpi_config]);
  275. #endif
  276. #ifdef RGBLIGHT_ENABLE
  277. rgblight_toggle_noeeprom(); //double toggle post init removes the weirdness with rgb strips having a yellow first LED
  278. rgblight_toggle_noeeprom();
  279. #endif
  280. #ifdef DYNAMIC_TAPPING_TERM_ENABLE
  281. tap_toggle(); // Need it to reevaluate this setting after initiating so that it is current after init
  282. tap_toggle();
  283. #endif
  284. keyboard_post_init_user();
  285. #ifdef OLED_ENABLE // purposefully after user post init to allow the RGB to startup first
  286. wait_ms(200); // Avoids a startup issue where the oled renders and then turns off with blackpill
  287. oled_on();
  288. #endif
  289. }