wt_main.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. /* Copyright 2018 Jason Williams (Wilba)
  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 "quantum.h"
  17. // Check that no backlight functions are called
  18. #if RGB_BACKLIGHT_ENABLED
  19. #include "keyboards/wilba_tech/wt_rgb_backlight.h"
  20. #endif // RGB_BACKLIGHT_ENABLED
  21. #ifdef WT_MONO_BACKLIGHT
  22. #include "keyboards/wilba_tech/wt_mono_backlight.h"
  23. #endif // WT_MONO_BACKLIGHT
  24. #include "keyboards/wilba_tech/via_api.h" // Temporary hack
  25. #include "keyboards/wilba_tech/via_keycodes.h" // Temporary hack
  26. #include "raw_hid.h"
  27. #include "dynamic_keymap.h"
  28. #include "timer.h"
  29. #include "tmk_core/common/eeprom.h"
  30. bool eeprom_is_valid(void)
  31. {
  32. return (eeprom_read_word(((void*)EEPROM_MAGIC_ADDR)) == EEPROM_MAGIC &&
  33. eeprom_read_byte(((void*)EEPROM_VERSION_ADDR)) == EEPROM_VERSION);
  34. }
  35. void eeprom_set_valid(bool valid)
  36. {
  37. eeprom_update_word(((void*)EEPROM_MAGIC_ADDR), valid ? EEPROM_MAGIC : 0xFFFF);
  38. eeprom_update_byte(((void*)EEPROM_VERSION_ADDR), valid ? EEPROM_VERSION : 0xFF);
  39. }
  40. void eeprom_reset(void)
  41. {
  42. // Set the Zeal60 specific EEPROM state as invalid.
  43. eeprom_set_valid(false);
  44. // Set the TMK/QMK EEPROM state as invalid.
  45. eeconfig_disable();
  46. }
  47. #ifdef RAW_ENABLE
  48. void raw_hid_receive( uint8_t *data, uint8_t length )
  49. {
  50. uint8_t *command_id = &(data[0]);
  51. uint8_t *command_data = &(data[1]);
  52. switch ( *command_id )
  53. {
  54. case id_get_protocol_version:
  55. {
  56. command_data[0] = PROTOCOL_VERSION >> 8;
  57. command_data[1] = PROTOCOL_VERSION & 0xFF;
  58. break;
  59. }
  60. case id_get_keyboard_value:
  61. {
  62. if ( command_data[0] == id_uptime )
  63. {
  64. uint32_t value = timer_read32();
  65. command_data[1] = (value >> 24 ) & 0xFF;
  66. command_data[2] = (value >> 16 ) & 0xFF;
  67. command_data[3] = (value >> 8 ) & 0xFF;
  68. command_data[4] = value & 0xFF;
  69. }
  70. else
  71. {
  72. *command_id = id_unhandled;
  73. }
  74. break;
  75. }
  76. #ifdef DYNAMIC_KEYMAP_ENABLE
  77. case id_dynamic_keymap_get_keycode:
  78. {
  79. uint16_t keycode = dynamic_keymap_get_keycode( command_data[0], command_data[1], command_data[2] );
  80. command_data[3] = keycode >> 8;
  81. command_data[4] = keycode & 0xFF;
  82. break;
  83. }
  84. case id_dynamic_keymap_set_keycode:
  85. {
  86. dynamic_keymap_set_keycode( command_data[0], command_data[1], command_data[2], ( command_data[3] << 8 ) | command_data[4] );
  87. break;
  88. }
  89. case id_dynamic_keymap_reset:
  90. {
  91. dynamic_keymap_reset();
  92. break;
  93. }
  94. case id_dynamic_keymap_macro_get_count:
  95. {
  96. command_data[0] = dynamic_keymap_macro_get_count();
  97. break;
  98. }
  99. case id_dynamic_keymap_macro_get_buffer_size:
  100. {
  101. uint16_t size = dynamic_keymap_macro_get_buffer_size();
  102. command_data[0] = size >> 8;
  103. command_data[1] = size & 0xFF;
  104. break;
  105. }
  106. case id_dynamic_keymap_macro_get_buffer:
  107. {
  108. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  109. uint16_t size = command_data[2]; // size <= 28
  110. dynamic_keymap_macro_get_buffer( offset, size, &command_data[3] );
  111. break;
  112. }
  113. case id_dynamic_keymap_macro_set_buffer:
  114. {
  115. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  116. uint16_t size = command_data[2]; // size <= 28
  117. dynamic_keymap_macro_set_buffer( offset, size, &command_data[3] );
  118. break;
  119. }
  120. case id_dynamic_keymap_macro_reset:
  121. {
  122. dynamic_keymap_macro_reset();
  123. break;
  124. }
  125. case id_dynamic_keymap_get_layer_count:
  126. {
  127. command_data[0] = dynamic_keymap_get_layer_count();
  128. break;
  129. }
  130. case id_dynamic_keymap_get_buffer:
  131. {
  132. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  133. uint16_t size = command_data[2]; // size <= 28
  134. dynamic_keymap_get_buffer( offset, size, &command_data[3] );
  135. break;
  136. }
  137. case id_dynamic_keymap_set_buffer:
  138. {
  139. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  140. uint16_t size = command_data[2]; // size <= 28
  141. dynamic_keymap_set_buffer( offset, size, &command_data[3] );
  142. break;
  143. }
  144. #endif // DYNAMIC_KEYMAP_ENABLE
  145. #if RGB_BACKLIGHT_ENABLED
  146. case id_backlight_config_set_value:
  147. {
  148. backlight_config_set_value(command_data);
  149. break;
  150. }
  151. case id_backlight_config_get_value:
  152. {
  153. backlight_config_get_value(command_data);
  154. break;
  155. }
  156. case id_backlight_config_save:
  157. {
  158. backlight_config_save();
  159. break;
  160. }
  161. #endif // RGB_BACKLIGHT_ENABLED
  162. case id_eeprom_reset:
  163. {
  164. eeprom_reset();
  165. break;
  166. }
  167. case id_bootloader_jump:
  168. {
  169. // Need to send data back before the jump
  170. // Informs host that the command is handled
  171. raw_hid_send( data, length );
  172. // Give host time to read it
  173. wait_ms(100);
  174. bootloader_jump();
  175. break;
  176. }
  177. default:
  178. {
  179. // Unhandled message.
  180. *command_id = id_unhandled;
  181. break;
  182. }
  183. }
  184. // Return same buffer with values changed
  185. raw_hid_send( data, length );
  186. }
  187. #endif
  188. void main_init(void)
  189. {
  190. // If the EEPROM has the magic, the data is good.
  191. // OK to load from EEPROM.
  192. if (eeprom_is_valid()) {
  193. #if RGB_BACKLIGHT_ENABLED
  194. backlight_config_load();
  195. #endif // RGB_BACKLIGHT_ENABLED
  196. } else {
  197. #if RGB_BACKLIGHT_ENABLED
  198. // If the EEPROM has not been saved before, or is out of date,
  199. // save the default values to the EEPROM. Default values
  200. // come from construction of the zeal_backlight_config instance.
  201. backlight_config_save();
  202. #endif // RGB_BACKLIGHT_ENABLED
  203. #ifdef DYNAMIC_KEYMAP_ENABLE
  204. // This resets the keymaps in EEPROM to what is in flash.
  205. dynamic_keymap_reset();
  206. // This resets the macros in EEPROM to nothing.
  207. dynamic_keymap_macro_reset();
  208. #endif // DYNAMIC_KEYMAP_ENABLE
  209. // Save the magic number last, in case saving was interrupted
  210. eeprom_set_valid(true);
  211. }
  212. #if RGB_BACKLIGHT_ENABLED
  213. // Initialize LED drivers for backlight.
  214. backlight_init_drivers();
  215. backlight_timer_init();
  216. backlight_timer_enable();
  217. #endif // RGB_BACKLIGHT_ENABLED
  218. #ifdef WT_MONO_BACKLIGHT
  219. // Initialize LED drivers for backlight.
  220. backlight_init_drivers();
  221. backlight_timer_init();
  222. backlight_timer_enable();
  223. #endif // WT_MONO_BACKLIGHT
  224. }
  225. void bootmagic_lite(void)
  226. {
  227. // The lite version of TMK's bootmagic.
  228. // 100% less potential for accidentally making the
  229. // keyboard do stupid things.
  230. // We need multiple scans because debouncing can't be turned off.
  231. matrix_scan();
  232. wait_ms(DEBOUNCE);
  233. wait_ms(DEBOUNCE);
  234. matrix_scan();
  235. // If the Esc (matrix 0,0) is held down on power up,
  236. // reset the EEPROM valid state and jump to bootloader.
  237. if ( matrix_get_row(0) & (1<<0) ) {
  238. eeprom_reset();
  239. bootloader_jump();
  240. }
  241. }
  242. void matrix_init_kb(void)
  243. {
  244. bootmagic_lite();
  245. main_init();
  246. matrix_init_user();
  247. }
  248. void matrix_scan_kb(void)
  249. {
  250. #if RGB_BACKLIGHT_ENABLED
  251. // This only updates the LED driver buffers if something has changed.
  252. backlight_update_pwm_buffers();
  253. #endif // RGB_BACKLIGHT_ENABLED
  254. #ifdef WT_MONO_BACKLIGHT
  255. // This only updates the LED driver buffers if something has changed.
  256. backlight_update_pwm_buffers();
  257. #endif
  258. matrix_scan_user();
  259. }
  260. bool process_record_kb(uint16_t keycode, keyrecord_t *record)
  261. {
  262. #if RGB_BACKLIGHT_ENABLED
  263. process_record_backlight(keycode, record);
  264. #endif // RGB_BACKLIGHT_ENABLED
  265. switch(keycode) {
  266. case FN_MO13:
  267. if (record->event.pressed) {
  268. layer_on(1);
  269. update_tri_layer(1, 2, 3);
  270. } else {
  271. layer_off(1);
  272. update_tri_layer(1, 2, 3);
  273. }
  274. return false;
  275. break;
  276. case FN_MO23:
  277. if (record->event.pressed) {
  278. layer_on(2);
  279. update_tri_layer(1, 2, 3);
  280. } else {
  281. layer_off(2);
  282. update_tri_layer(1, 2, 3);
  283. }
  284. return false;
  285. break;
  286. }
  287. #ifdef DYNAMIC_KEYMAP_ENABLE
  288. // Handle macros
  289. if (record->event.pressed) {
  290. if ( keycode >= MACRO00 && keycode <= MACRO15 )
  291. {
  292. uint8_t id = keycode - MACRO00;
  293. dynamic_keymap_macro_send(id);
  294. return false;
  295. }
  296. }
  297. #endif //DYNAMIC_KEYMAP_ENABLE
  298. return process_record_user(keycode, record);
  299. }
  300. // This overrides the one in quantum/keymap_common.c
  301. uint16_t keymap_function_id_to_action( uint16_t function_id )
  302. {
  303. // Zeal60 specific "action functions" are 0xF00 to 0xFFF
  304. // i.e. F(0xF00) to F(0xFFF) are mapped to
  305. // enum zeal60_action_functions by masking last 8 bits.
  306. if ( function_id >= 0x0F00 && function_id <= 0x0FFF )
  307. {
  308. uint8_t id = function_id & 0xFF;
  309. switch ( id ) {
  310. case TRIPLE_TAP_1_3:
  311. case TRIPLE_TAP_2_3:
  312. {
  313. return ACTION_FUNCTION_TAP(id);
  314. break;
  315. }
  316. default:
  317. break;
  318. }
  319. }
  320. return pgm_read_word(&fn_actions[function_id]);
  321. }
  322. // Zeal60 specific "action functions"
  323. void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
  324. {
  325. switch (id)
  326. {
  327. case TRIPLE_TAP_1_3:
  328. case TRIPLE_TAP_2_3:
  329. if (record->event.pressed) {
  330. layer_on( id == TRIPLE_TAP_1_3 ? 1 : 2 );
  331. if (record->tap.count && !record->tap.interrupted) {
  332. if (record->tap.count >= 3) {
  333. layer_invert(3);
  334. }
  335. } else {
  336. record->tap.count = 0;
  337. }
  338. } else {
  339. layer_off( id == TRIPLE_TAP_1_3 ? 1 : 2 );
  340. }
  341. break;
  342. }
  343. }
  344. void led_set_kb(uint8_t usb_led)
  345. {
  346. #if RGB_BACKLIGHT_ENABLED
  347. backlight_set_indicator_state(usb_led);
  348. #endif // RGB_BACKLIGHT_ENABLED
  349. }
  350. void suspend_power_down_kb(void)
  351. {
  352. #if RGB_BACKLIGHT_ENABLED
  353. backlight_set_suspend_state(true);
  354. #endif // RGB_BACKLIGHT_ENABLED
  355. }
  356. void suspend_wakeup_init_kb(void)
  357. {
  358. #if RGB_BACKLIGHT_ENABLED
  359. backlight_set_suspend_state(false);
  360. #endif // RGB_BACKLIGHT_ENABLED
  361. }