keyboard.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. #include "keyboard.h"
  2. #include "ch.h"
  3. #include "hal.h"
  4. #include "led_custom.h"
  5. #include "util.h"
  6. #include "quantum.h"
  7. #include "ws2812.h"
  8. #include "raw_hid.h"
  9. #include "dynamic_keymap.h"
  10. #include "tmk_core/common/eeprom.h"
  11. // HACK
  12. #include "keyboards/zeal60/zeal60_api.h" // Temporary hack
  13. #include "keyboards/zeal60/zeal60_keycodes.h" // Temporary hack
  14. backlight_config_t kb_backlight_config = {
  15. .enable = true,
  16. .breathing = true,
  17. .level = BACKLIGHT_LEVELS
  18. };
  19. bool eeprom_is_valid(void)
  20. {
  21. return (eeprom_read_word(((void*)EEPROM_MAGIC_ADDR)) == EEPROM_MAGIC &&
  22. eeprom_read_byte(((void*)EEPROM_VERSION_ADDR)) == EEPROM_VERSION);
  23. }
  24. void eeprom_set_valid(bool valid)
  25. {
  26. eeprom_update_word(((void*)EEPROM_MAGIC_ADDR), valid ? EEPROM_MAGIC : 0xFFFF);
  27. eeprom_update_byte(((void*)EEPROM_VERSION_ADDR), valid ? EEPROM_VERSION : 0xFF);
  28. }
  29. void eeprom_reset(void)
  30. {
  31. eeprom_set_valid(false);
  32. eeconfig_disable();
  33. }
  34. void save_backlight_config_to_eeprom(){
  35. eeprom_update_byte((uint8_t*)EEPROM_CUSTOM_BACKLIGHT, kb_backlight_config.raw);
  36. }
  37. void load_custom_config(){
  38. kb_backlight_config.raw = eeprom_read_byte((uint8_t*)EEPROM_CUSTOM_BACKLIGHT);
  39. }
  40. #ifdef DYNAMIC_KEYMAP_ENABLE
  41. void dynamic_keymap_custom_reset(void){
  42. void *p = (void*)(EEPROM_CUSTOM_BACKLIGHT);
  43. void *end = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR);
  44. while ( p != end ) {
  45. eeprom_update_byte(p, 0);
  46. ++p;
  47. }
  48. }
  49. #endif
  50. void eeprom_init_kb(void)
  51. {
  52. // If the EEPROM has the magic, the data is good.
  53. // OK to load from EEPROM.
  54. if (eeprom_is_valid()) {
  55. load_custom_config();
  56. } else {
  57. #ifdef DYNAMIC_KEYMAP_ENABLE
  58. // This resets the keymaps in EEPROM to what is in flash.
  59. dynamic_keymap_reset();
  60. // This resets the macros in EEPROM to nothing.
  61. dynamic_keymap_macro_reset();
  62. // Reset the custom stuff
  63. dynamic_keymap_custom_reset();
  64. #endif
  65. // Save the magic number last, in case saving was interrupted
  66. save_backlight_config_to_eeprom();
  67. eeprom_set_valid(true);
  68. }
  69. }
  70. __attribute__ ((weak))
  71. void matrix_init_board(void);
  72. void matrix_init_kb(void){
  73. eeprom_init_kb();
  74. /* MOSI pin*/
  75. palSetPadMode(PORT_WS2812, PIN_WS2812, PAL_MODE_ALTERNATE(0));
  76. wait_ms(500);
  77. #ifdef RGBLIGHT_ENABLE
  78. leds_init();
  79. #endif
  80. backlight_init_ports();
  81. matrix_init_board();
  82. }
  83. void matrix_scan_kb(void)
  84. {
  85. #ifdef RGBLIGHT_ENABLE
  86. rgblight_task();
  87. #endif
  88. }
  89. bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
  90. switch (keycode) {
  91. case BL_INC:
  92. if (record->event.pressed) {
  93. kb_backlight_config.level = kb_backlight_config.level + 1;
  94. if(kb_backlight_config.level > BACKLIGHT_LEVELS){
  95. kb_backlight_config.level = BACKLIGHT_LEVELS;
  96. }
  97. backlight_set(kb_backlight_config.level);
  98. save_backlight_config_to_eeprom();
  99. }
  100. return false;
  101. case BL_TOGG:
  102. if (record->event.pressed) {
  103. kb_backlight_config.enable = !kb_backlight_config.enable;
  104. if(kb_backlight_config.enable){
  105. backlight_set(kb_backlight_config.level);
  106. } else {
  107. backlight_set(0);
  108. }
  109. save_backlight_config_to_eeprom();
  110. }
  111. return false;
  112. case BL_DEC:
  113. if (record->event.pressed) {
  114. if(kb_backlight_config.level <= 1){
  115. kb_backlight_config.level = 0;
  116. } else {
  117. kb_backlight_config.level = kb_backlight_config.level - 1;
  118. }
  119. backlight_set(kb_backlight_config.level);
  120. save_backlight_config_to_eeprom();
  121. }
  122. return false;
  123. case BL_BRTG:
  124. if (record->event.pressed) {
  125. kb_backlight_config.breathing = !kb_backlight_config.breathing;
  126. breathing_toggle();
  127. save_backlight_config_to_eeprom();
  128. }
  129. return false;
  130. default:
  131. break;
  132. }
  133. #ifdef DYNAMIC_KEYMAP_ENABLE
  134. // Handle macros
  135. if (record->event.pressed) {
  136. if ( keycode >= MACRO00 && keycode <= MACRO15 )
  137. {
  138. uint8_t id = keycode - MACRO00;
  139. dynamic_keymap_macro_send(id);
  140. return false;
  141. }
  142. }
  143. #endif //DYNAMIC_KEYMAP_ENABLE
  144. return true;
  145. }
  146. // Start Dynamic Keymap code
  147. #ifdef RAW_ENABLE
  148. void raw_hid_receive( uint8_t *data, uint8_t length )
  149. {
  150. uint8_t *command_id = &(data[0]);
  151. uint8_t *command_data = &(data[1]);
  152. switch ( *command_id )
  153. {
  154. case id_get_protocol_version:
  155. {
  156. command_data[0] = PROTOCOL_VERSION >> 8;
  157. command_data[1] = PROTOCOL_VERSION & 0xFF;
  158. break;
  159. }
  160. case id_get_keyboard_value:
  161. {
  162. switch( command_data[0])
  163. {
  164. case id_uptime:
  165. {
  166. uint32_t value = timer_read32();
  167. command_data[1] = (value >> 24 ) & 0xFF;
  168. command_data[2] = (value >> 16 ) & 0xFF;
  169. command_data[3] = (value >> 8 ) & 0xFF;
  170. command_data[4] = value & 0xFF;
  171. break;
  172. }
  173. default:
  174. {
  175. *command_id = id_unhandled;
  176. break;
  177. }
  178. }
  179. break;
  180. }
  181. #ifdef DYNAMIC_KEYMAP_ENABLE
  182. case id_dynamic_keymap_get_keycode:
  183. {
  184. uint16_t keycode = dynamic_keymap_get_keycode( command_data[0], command_data[1], command_data[2] );
  185. command_data[3] = keycode >> 8;
  186. command_data[4] = keycode & 0xFF;
  187. break;
  188. }
  189. case id_dynamic_keymap_set_keycode:
  190. {
  191. dynamic_keymap_set_keycode( command_data[0], command_data[1], command_data[2], ( command_data[3] << 8 ) | command_data[4] );
  192. break;
  193. }
  194. case id_dynamic_keymap_reset:
  195. {
  196. dynamic_keymap_reset();
  197. break;
  198. }
  199. case id_dynamic_keymap_macro_get_count:
  200. {
  201. command_data[0] = dynamic_keymap_macro_get_count();
  202. break;
  203. }
  204. case id_dynamic_keymap_macro_get_buffer_size:
  205. {
  206. uint16_t size = dynamic_keymap_macro_get_buffer_size();
  207. command_data[0] = size >> 8;
  208. command_data[1] = size & 0xFF;
  209. break;
  210. }
  211. case id_dynamic_keymap_macro_get_buffer:
  212. {
  213. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  214. uint16_t size = command_data[2]; // size <= 28
  215. dynamic_keymap_macro_get_buffer( offset, size, &command_data[3] );
  216. break;
  217. }
  218. case id_dynamic_keymap_macro_set_buffer:
  219. {
  220. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  221. uint16_t size = command_data[2]; // size <= 28
  222. dynamic_keymap_macro_set_buffer( offset, size, &command_data[3] );
  223. break;
  224. }
  225. case id_dynamic_keymap_macro_reset:
  226. {
  227. dynamic_keymap_macro_reset();
  228. break;
  229. }
  230. case id_dynamic_keymap_get_layer_count:
  231. {
  232. command_data[0] = dynamic_keymap_get_layer_count();
  233. break;
  234. }
  235. case id_dynamic_keymap_get_buffer:
  236. {
  237. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  238. uint16_t size = command_data[2]; // size <= 28
  239. dynamic_keymap_get_buffer( offset, size, &command_data[3] );
  240. break;
  241. }
  242. case id_dynamic_keymap_set_buffer:
  243. {
  244. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  245. uint16_t size = command_data[2]; // size <= 28
  246. dynamic_keymap_set_buffer( offset, size, &command_data[3] );
  247. break;
  248. }
  249. #endif // DYNAMIC_KEYMAP_ENABLE
  250. case id_eeprom_reset:
  251. {
  252. eeprom_reset();
  253. break;
  254. }
  255. case id_bootloader_jump:
  256. {
  257. // Need to send data back before the jump
  258. // Informs host that the command is handled
  259. raw_hid_send( data, length );
  260. // Give host time to read it
  261. wait_ms(100);
  262. bootloader_jump();
  263. break;
  264. }
  265. default:
  266. {
  267. // Unhandled message.
  268. *command_id = id_unhandled;
  269. break;
  270. }
  271. }
  272. // Return same buffer with values changed
  273. raw_hid_send( data, length );
  274. }
  275. #endif