wt_main.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  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. #if MONO_BACKLIGHT_ENABLED
  22. #include "keyboards/wilba_tech/wt_mono_backlight.h"
  23. #endif // MONO_BACKLIGHT_ENABLED
  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 || MONO_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 || MONO_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 || MONO_BACKLIGHT_ENABLED
  194. backlight_config_load();
  195. #endif // RGB_BACKLIGHT_ENABLED || MONO_BACKLIGHT_ENABLED
  196. } else {
  197. #if RGB_BACKLIGHT_ENABLED || MONO_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 backlight_config instance.
  201. backlight_config_save();
  202. #endif // RGB_BACKLIGHT_ENABLED || MONO_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 || MONO_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 || MONO_BACKLIGHT_ENABLED
  218. }
  219. void bootmagic_lite(void)
  220. {
  221. // The lite version of TMK's bootmagic.
  222. // 100% less potential for accidentally making the
  223. // keyboard do stupid things.
  224. // We need multiple scans because debouncing can't be turned off.
  225. matrix_scan();
  226. wait_ms(DEBOUNCE);
  227. wait_ms(DEBOUNCE);
  228. matrix_scan();
  229. // If the Esc (matrix 0,0) is held down on power up,
  230. // reset the EEPROM valid state and jump to bootloader.
  231. if ( matrix_get_row(0) & (1<<0) ) {
  232. eeprom_reset();
  233. bootloader_jump();
  234. }
  235. }
  236. void matrix_init_kb(void)
  237. {
  238. bootmagic_lite();
  239. main_init();
  240. matrix_init_user();
  241. }
  242. void matrix_scan_kb(void)
  243. {
  244. #if RGB_BACKLIGHT_ENABLED || MONO_BACKLIGHT_ENABLED
  245. // This only updates the LED driver buffers if something has changed.
  246. backlight_update_pwm_buffers();
  247. #endif // RGB_BACKLIGHT_ENABLED || MONO_BACKLIGHT_ENABLED
  248. matrix_scan_user();
  249. }
  250. bool process_record_kb(uint16_t keycode, keyrecord_t *record)
  251. {
  252. #if RGB_BACKLIGHT_ENABLED || MONO_BACKLIGHT_ENABLED
  253. process_record_backlight(keycode, record);
  254. #endif // RGB_BACKLIGHT_ENABLED || MONO_BACKLIGHT_ENABLED
  255. switch(keycode) {
  256. case FN_MO13:
  257. if (record->event.pressed) {
  258. layer_on(1);
  259. update_tri_layer(1, 2, 3);
  260. } else {
  261. layer_off(1);
  262. update_tri_layer(1, 2, 3);
  263. }
  264. return false;
  265. break;
  266. case FN_MO23:
  267. if (record->event.pressed) {
  268. layer_on(2);
  269. update_tri_layer(1, 2, 3);
  270. } else {
  271. layer_off(2);
  272. update_tri_layer(1, 2, 3);
  273. }
  274. return false;
  275. break;
  276. }
  277. #ifdef DYNAMIC_KEYMAP_ENABLE
  278. // Handle macros
  279. if (record->event.pressed) {
  280. if ( keycode >= MACRO00 && keycode <= MACRO15 )
  281. {
  282. uint8_t id = keycode - MACRO00;
  283. dynamic_keymap_macro_send(id);
  284. return false;
  285. }
  286. }
  287. #endif //DYNAMIC_KEYMAP_ENABLE
  288. return process_record_user(keycode, record);
  289. }
  290. // This overrides the one in quantum/keymap_common.c
  291. uint16_t keymap_function_id_to_action( uint16_t function_id )
  292. {
  293. // Zeal60 specific "action functions" are 0xF00 to 0xFFF
  294. // i.e. F(0xF00) to F(0xFFF) are mapped to
  295. // enum zeal60_action_functions by masking last 8 bits.
  296. if ( function_id >= 0x0F00 && function_id <= 0x0FFF )
  297. {
  298. uint8_t id = function_id & 0xFF;
  299. switch ( id ) {
  300. case TRIPLE_TAP_1_3:
  301. case TRIPLE_TAP_2_3:
  302. {
  303. return ACTION_FUNCTION_TAP(id);
  304. break;
  305. }
  306. default:
  307. break;
  308. }
  309. }
  310. return pgm_read_word(&fn_actions[function_id]);
  311. }
  312. // Zeal60 specific "action functions"
  313. void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
  314. {
  315. switch (id)
  316. {
  317. case TRIPLE_TAP_1_3:
  318. case TRIPLE_TAP_2_3:
  319. if (record->event.pressed) {
  320. layer_on( id == TRIPLE_TAP_1_3 ? 1 : 2 );
  321. if (record->tap.count && !record->tap.interrupted) {
  322. if (record->tap.count >= 3) {
  323. layer_invert(3);
  324. }
  325. } else {
  326. record->tap.count = 0;
  327. }
  328. } else {
  329. layer_off( id == TRIPLE_TAP_1_3 ? 1 : 2 );
  330. }
  331. break;
  332. }
  333. }
  334. void led_set_kb(uint8_t usb_led)
  335. {
  336. #if RGB_BACKLIGHT_ENABLED || MONO_BACKLIGHT_ENABLED
  337. backlight_set_indicator_state(usb_led);
  338. #endif // RGB_BACKLIGHT_ENABLED || MONO_BACKLIGHT_ENABLED
  339. led_set_user(usb_led);
  340. }
  341. void suspend_power_down_kb(void)
  342. {
  343. #if RGB_BACKLIGHT_ENABLED || MONO_BACKLIGHT_ENABLED
  344. backlight_set_suspend_state(true);
  345. #endif // RGB_BACKLIGHT_ENABLED || MONO_BACKLIGHT_ENABLED
  346. }
  347. void suspend_wakeup_init_kb(void)
  348. {
  349. #if RGB_BACKLIGHT_ENABLED || MONO_BACKLIGHT_ENABLED
  350. backlight_set_suspend_state(false);
  351. #endif // RGB_BACKLIGHT_ENABLED || MONO_BACKLIGHT_ENABLED
  352. }