logo

qmk_firmware

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

mschwingen.c (6532B)


  1. /*
  2. * Copyright 2020 Michael Schwingen
  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 <util/delay.h>
  17. #include "mschwingen.h"
  18. #include "uart.h"
  19. #include "print.h"
  20. #include "sendchar.h"
  21. #include "sleep_led.h"
  22. #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
  23. #include "ws2812.h"
  24. #endif
  25. #ifdef UART_DEBUG
  26. # undef sendchar
  27. static int8_t capture_sendchar(uint8_t c) {
  28. // sendchar(c);
  29. uart_write(c);
  30. return 0;
  31. }
  32. #endif
  33. static uint16_t blink_cycle_timer;
  34. static bool blink_state = false;
  35. static uint8_t isRecording = 0;
  36. #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
  37. # if RGBLIGHT_LED_COUNT < 3
  38. # error we need at least 3 RGB LEDs!
  39. # endif
  40. # define BRIGHT 32
  41. # define DIM 6
  42. static led_t led_state;
  43. static uint8_t layer;
  44. static uint8_t default_layer;
  45. #endif
  46. // we need our own sleep_led_* implementation to get callbacks on USB
  47. // suspend/resume in order to completely turn off WS2812 LEDs
  48. static bool suspend_active = false;
  49. void sleep_led_init(void) {}
  50. void sleep_led_toggle(void) {}
  51. void sleep_led_disable(void) {
  52. suspend_active = false;
  53. gpio_write_pin_high(MODELM_STATUS_LED);
  54. }
  55. void sleep_led_enable(void) {
  56. suspend_active = true;
  57. gpio_write_pin_low(MODELM_STATUS_LED);
  58. #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
  59. ws2812_set_color_all(0, 0, 0);
  60. ws2812_flush();
  61. #endif
  62. }
  63. void keyboard_pre_init_kb(void) {
  64. #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
  65. ws2812_init();
  66. ws2812_flush();
  67. #else
  68. /* Set status LEDs pins to output and Low (on) */
  69. gpio_set_pin_output(MODELM_LED_CAPSLOCK);
  70. gpio_set_pin_output(MODELM_LED_SCROLLOCK);
  71. gpio_set_pin_output(MODELM_LED_NUMLOCK);
  72. gpio_write_pin_low(MODELM_LED_CAPSLOCK);
  73. gpio_write_pin_low(MODELM_LED_SCROLLOCK);
  74. gpio_write_pin_low(MODELM_LED_NUMLOCK);
  75. #endif
  76. gpio_set_pin_output(MODELM_STATUS_LED);
  77. gpio_write_pin_high(MODELM_STATUS_LED);
  78. _delay_ms(50);
  79. #ifdef UART_DEBUG
  80. uart_init(115200);
  81. print_set_sendchar(capture_sendchar);
  82. uprintf("\r\nHello world!\r\n");
  83. #endif
  84. gpio_set_pin_output(SR_LOAD_PIN);
  85. gpio_set_pin_output(SR_CLK_PIN);
  86. gpio_set_pin_output(SR_DOUT_PIN); // MOSI - unused
  87. gpio_write_pin_low(SR_CLK_PIN);
  88. keyboard_pre_init_user();
  89. }
  90. #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
  91. static void led_update_rgb(void) {
  92. if (isRecording && blink_state) {
  93. ws2812_set_color(0, BRIGHT, BRIGHT, BRIGHT);
  94. } else {
  95. switch (default_layer) {
  96. case 0:
  97. if (led_state.num_lock) {
  98. ws2812_set_color(0, 0, 0, BRIGHT);
  99. } else {
  100. ws2812_set_color(0, 0, 0, DIM);
  101. }
  102. break;
  103. case 1:
  104. if (led_state.num_lock) {
  105. ws2812_set_color(0, 0, BRIGHT, 0);
  106. } else {
  107. ws2812_set_color(0, 0, 0, 0);
  108. }
  109. break;
  110. }
  111. }
  112. if (led_state.caps_lock) {
  113. ws2812_set_color(1, 0, BRIGHT, 0);
  114. } else {
  115. ws2812_set_color(1, 0, 0, 0);
  116. }
  117. switch (layer) {
  118. case 0:
  119. case 1:
  120. default:
  121. if (led_state.scroll_lock) {
  122. ws2812_set_color(2, 0, BRIGHT, 0);
  123. } else {
  124. ws2812_set_color(2, 0, 0, 0);
  125. }
  126. break;
  127. case 2:
  128. if (led_state.scroll_lock) {
  129. ws2812_set_color(2, BRIGHT, 0, 0);
  130. } else {
  131. ws2812_set_color(2, DIM, 0, 0);
  132. }
  133. break;
  134. case 3:
  135. if (led_state.scroll_lock) {
  136. ws2812_set_color(2, 0, BRIGHT, BRIGHT);
  137. } else {
  138. ws2812_set_color(2, 0, DIM, DIM);
  139. }
  140. break;
  141. }
  142. if (!suspend_active) {
  143. ws2812_flush();
  144. }
  145. }
  146. bool led_update_kb(led_t state) {
  147. dprintf("LED Update: %d %d %d", led_state.num_lock, led_state.caps_lock, led_state.scroll_lock);
  148. led_state = state;
  149. led_update_rgb();
  150. return true;
  151. }
  152. void update_layer_leds(void) {
  153. static uint8_t old_layer = 255;
  154. static uint8_t old_default_layer = 255;
  155. layer = get_highest_layer(layer_state);
  156. default_layer = get_highest_layer(default_layer_state);
  157. if (isRecording && timer_elapsed(blink_cycle_timer) > 150) {
  158. blink_state = !blink_state;
  159. blink_cycle_timer = timer_read();
  160. old_layer = 255; // fallthrough next check
  161. }
  162. if (layer == old_layer && default_layer == old_default_layer) {
  163. return;
  164. }
  165. old_layer = layer;
  166. old_default_layer = default_layer;
  167. dprintf("Layer change: %d %d", default_layer, layer);
  168. led_update_rgb();
  169. }
  170. /*****************************************************************************/
  171. #else // classic LEDs on GPIO
  172. bool led_update_kb(led_t led_state) {
  173. dprintf("LED Update: %d %d %d", led_state.num_lock, led_state.caps_lock, led_state.scroll_lock);
  174. if (led_update_user(led_state)) {
  175. if (!isRecording) gpio_write_pin(MODELM_LED_NUMLOCK, !led_state.num_lock);
  176. gpio_write_pin(MODELM_LED_CAPSLOCK, !led_state.caps_lock);
  177. gpio_write_pin(MODELM_LED_SCROLLOCK, !led_state.scroll_lock);
  178. }
  179. return true;
  180. }
  181. void update_layer_leds(void) {
  182. if (isRecording && timer_elapsed(blink_cycle_timer) > 150) {
  183. blink_state = !blink_state;
  184. blink_cycle_timer = timer_read();
  185. gpio_write_pin(MODELM_LED_NUMLOCK, blink_state);
  186. }
  187. }
  188. #endif
  189. bool dynamic_macro_record_start_kb(int8_t direction) {
  190. if (!dynamic_macro_record_start_user(direction)) {
  191. return false;
  192. }
  193. isRecording++;
  194. blink_cycle_timer = timer_read();
  195. return true;
  196. }
  197. bool dynamic_macro_record_end_kb(int8_t direction) {
  198. if (!dynamic_macro_record_end_user(direction)) {
  199. return false;
  200. }
  201. if (isRecording) isRecording--;
  202. return true;
  203. }