satisfaction75.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. #include "satisfaction75.h"
  2. #include "print.h"
  3. #include "debug.h"
  4. #include "ch.h"
  5. #include "hal.h"
  6. #ifdef QWIIC_MICRO_OLED_ENABLE
  7. #include "micro_oled.h"
  8. #include "qwiic.h"
  9. #endif
  10. #include "timer.h"
  11. #include "raw_hid.h"
  12. #include "dynamic_keymap.h"
  13. #include "tmk_core/common/eeprom.h"
  14. // HACK
  15. #include "keyboards/wilba_tech/via_api.h" // Temporary hack
  16. #include "keyboards/wilba_tech/via_keycodes.h" // Temporary hack
  17. /* Artificial delay added to get media keys to work in the encoder*/
  18. #define MEDIA_KEY_DELAY 10
  19. uint16_t last_flush;
  20. volatile uint8_t led_numlock = false;
  21. volatile uint8_t led_capslock = false;
  22. volatile uint8_t led_scrolllock = false;
  23. uint8_t layer;
  24. bool queue_for_send = false;
  25. bool clock_set_mode = false;
  26. uint8_t oled_mode = OLED_DEFAULT;
  27. bool oled_sleeping = false;
  28. uint8_t encoder_value = 32;
  29. uint8_t encoder_mode = ENC_MODE_VOLUME;
  30. uint8_t enabled_encoder_modes = 0x1F;
  31. RTCDateTime last_timespec;
  32. uint16_t last_minute = 0;
  33. uint8_t time_config_idx = 0;
  34. int8_t hour_config = 0;
  35. int16_t minute_config = 0;
  36. int8_t year_config = 0;
  37. int8_t month_config = 0;
  38. int8_t day_config = 0;
  39. uint8_t previous_encoder_mode = 0;
  40. backlight_config_t kb_backlight_config = {
  41. .enable = true,
  42. .breathing = true,
  43. .level = BACKLIGHT_LEVELS
  44. };
  45. bool eeprom_is_valid(void)
  46. {
  47. return (eeprom_read_word(((void*)EEPROM_MAGIC_ADDR)) == EEPROM_MAGIC &&
  48. eeprom_read_byte(((void*)EEPROM_VERSION_ADDR)) == EEPROM_VERSION);
  49. }
  50. void eeprom_set_valid(bool valid)
  51. {
  52. eeprom_update_word(((void*)EEPROM_MAGIC_ADDR), valid ? EEPROM_MAGIC : 0xFFFF);
  53. eeprom_update_byte(((void*)EEPROM_VERSION_ADDR), valid ? EEPROM_VERSION : 0xFF);
  54. }
  55. void eeprom_reset(void)
  56. {
  57. // Set the VIA specific EEPROM state as invalid.
  58. eeprom_set_valid(false);
  59. // Set the TMK/QMK EEPROM state as invalid.
  60. eeconfig_disable();
  61. }
  62. #ifdef RAW_ENABLE
  63. void raw_hid_receive( uint8_t *data, uint8_t length )
  64. {
  65. uint8_t *command_id = &(data[0]);
  66. uint8_t *command_data = &(data[1]);
  67. switch ( *command_id )
  68. {
  69. case id_get_protocol_version:
  70. {
  71. command_data[0] = PROTOCOL_VERSION >> 8;
  72. command_data[1] = PROTOCOL_VERSION & 0xFF;
  73. break;
  74. }
  75. case id_get_keyboard_value:
  76. {
  77. switch( command_data[0])
  78. {
  79. case id_uptime:
  80. {
  81. uint32_t value = timer_read32();
  82. command_data[1] = (value >> 24 ) & 0xFF;
  83. command_data[2] = (value >> 16 ) & 0xFF;
  84. command_data[3] = (value >> 8 ) & 0xFF;
  85. command_data[4] = value & 0xFF;
  86. break;
  87. }
  88. case id_oled_default_mode:
  89. {
  90. uint8_t default_oled = eeprom_read_byte((uint8_t*)DYNAMIC_KEYMAP_DEFAULT_OLED);
  91. command_data[1] = default_oled;
  92. break;
  93. }
  94. case id_oled_mode:
  95. {
  96. command_data[1] = oled_mode;
  97. break;
  98. }
  99. case id_encoder_modes:
  100. {
  101. command_data[1] = enabled_encoder_modes;
  102. break;
  103. }
  104. case id_encoder_custom:
  105. {
  106. uint8_t custom_encoder_idx = command_data[1];
  107. uint16_t keycode = retrieve_custom_encoder_config(custom_encoder_idx, ENC_CUSTOM_CW);
  108. command_data[2] = keycode >> 8;
  109. command_data[3] = keycode & 0xFF;
  110. keycode = retrieve_custom_encoder_config(custom_encoder_idx, ENC_CUSTOM_CCW);
  111. command_data[4] = keycode >> 8;
  112. command_data[5] = keycode & 0xFF;
  113. keycode = retrieve_custom_encoder_config(custom_encoder_idx, ENC_CUSTOM_PRESS);
  114. command_data[6] = keycode >> 8;
  115. command_data[7] = keycode & 0xFF;
  116. break;
  117. }
  118. default:
  119. {
  120. *command_id = id_unhandled;
  121. break;
  122. }
  123. }
  124. break;
  125. }
  126. #ifdef DYNAMIC_KEYMAP_ENABLE
  127. case id_set_keyboard_value:
  128. {
  129. switch(command_data[0]){
  130. case id_oled_default_mode:
  131. {
  132. eeprom_update_byte((uint8_t*)DYNAMIC_KEYMAP_DEFAULT_OLED, command_data[1]);
  133. break;
  134. }
  135. case id_oled_mode:
  136. {
  137. oled_mode = command_data[1];
  138. draw_ui();
  139. break;
  140. }
  141. case id_encoder_modes:
  142. {
  143. enabled_encoder_modes = command_data[1];
  144. eeprom_update_byte((uint8_t*)DYNAMIC_KEYMAP_ENABLED_ENCODER_MODES, enabled_encoder_modes);
  145. break;
  146. }
  147. case id_encoder_custom:
  148. {
  149. uint8_t custom_encoder_idx = command_data[1];
  150. uint8_t encoder_behavior = command_data[2];
  151. uint16_t keycode = (command_data[3] << 8) | command_data[4];
  152. set_custom_encoder_config(custom_encoder_idx, encoder_behavior, keycode);
  153. break;
  154. }
  155. default:
  156. {
  157. *command_id = id_unhandled;
  158. break;
  159. }
  160. }
  161. break;
  162. }
  163. case id_dynamic_keymap_get_keycode:
  164. {
  165. uint16_t keycode = dynamic_keymap_get_keycode( command_data[0], command_data[1], command_data[2] );
  166. command_data[3] = keycode >> 8;
  167. command_data[4] = keycode & 0xFF;
  168. break;
  169. }
  170. case id_dynamic_keymap_set_keycode:
  171. {
  172. dynamic_keymap_set_keycode( command_data[0], command_data[1], command_data[2], ( command_data[3] << 8 ) | command_data[4] );
  173. break;
  174. }
  175. case id_dynamic_keymap_reset:
  176. {
  177. dynamic_keymap_reset();
  178. break;
  179. }
  180. case id_dynamic_keymap_macro_get_count:
  181. {
  182. command_data[0] = dynamic_keymap_macro_get_count();
  183. break;
  184. }
  185. case id_dynamic_keymap_macro_get_buffer_size:
  186. {
  187. uint16_t size = dynamic_keymap_macro_get_buffer_size();
  188. command_data[0] = size >> 8;
  189. command_data[1] = size & 0xFF;
  190. break;
  191. }
  192. case id_dynamic_keymap_macro_get_buffer:
  193. {
  194. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  195. uint16_t size = command_data[2]; // size <= 28
  196. dynamic_keymap_macro_set_buffer( offset, size, &command_data[3] );
  197. break;
  198. }
  199. case id_dynamic_keymap_macro_reset:
  200. {
  201. dynamic_keymap_macro_reset();
  202. break;
  203. }
  204. case id_dynamic_keymap_get_layer_count:
  205. {
  206. command_data[0] = dynamic_keymap_get_layer_count();
  207. break;
  208. }
  209. case id_dynamic_keymap_get_buffer:
  210. {
  211. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  212. uint16_t size = command_data[2]; // size <= 28
  213. dynamic_keymap_get_buffer( offset, size, &command_data[3] );
  214. break;
  215. }
  216. case id_dynamic_keymap_set_buffer:
  217. {
  218. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  219. uint16_t size = command_data[2]; // size <= 28
  220. dynamic_keymap_set_buffer( offset, size, &command_data[3] );
  221. break;
  222. }
  223. #endif // DYNAMIC_KEYMAP_ENABLE
  224. case id_eeprom_reset:
  225. {
  226. eeprom_reset();
  227. break;
  228. }
  229. case id_bootloader_jump:
  230. {
  231. // Need to send data back before the jump
  232. // Informs host that the command is handled
  233. raw_hid_send( data, length );
  234. // Give host time to read it
  235. wait_ms(100);
  236. bootloader_jump();
  237. break;
  238. }
  239. default:
  240. {
  241. // Unhandled message.
  242. *command_id = id_unhandled;
  243. break;
  244. }
  245. }
  246. // Return same buffer with values changed
  247. raw_hid_send( data, length );
  248. }
  249. #endif
  250. void read_host_led_state(void) {
  251. uint8_t leds = host_keyboard_leds();
  252. if (leds & (1 << USB_LED_NUM_LOCK)) {
  253. if (led_numlock == false){
  254. led_numlock = true;}
  255. } else {
  256. if (led_numlock == true){
  257. led_numlock = false;}
  258. }
  259. if (leds & (1 << USB_LED_CAPS_LOCK)) {
  260. if (led_capslock == false){
  261. led_capslock = true;}
  262. } else {
  263. if (led_capslock == true){
  264. led_capslock = false;}
  265. }
  266. if (leds & (1 << USB_LED_SCROLL_LOCK)) {
  267. if (led_scrolllock == false){
  268. led_scrolllock = true;}
  269. } else {
  270. if (led_scrolllock == true){
  271. led_scrolllock = false;}
  272. }
  273. }
  274. uint32_t layer_state_set_kb(uint32_t state) {
  275. state = layer_state_set_user(state);
  276. layer = biton32(state);
  277. queue_for_send = true;
  278. return state;
  279. }
  280. bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
  281. queue_for_send = true;
  282. switch (keycode) {
  283. case OLED_TOGG:
  284. if(!clock_set_mode){
  285. if (record->event.pressed) {
  286. oled_mode = (oled_mode + 1) % _NUM_OLED_MODES;
  287. draw_ui();
  288. }
  289. }
  290. return false;
  291. case CLOCK_SET:
  292. if (record->event.pressed) {
  293. if(clock_set_mode){
  294. pre_encoder_mode_change();
  295. clock_set_mode = false;
  296. encoder_mode = previous_encoder_mode;
  297. post_encoder_mode_change();
  298. }else{
  299. previous_encoder_mode = encoder_mode;
  300. pre_encoder_mode_change();
  301. clock_set_mode = true;
  302. encoder_mode = ENC_MODE_CLOCK_SET;
  303. post_encoder_mode_change();
  304. }
  305. }
  306. return false;
  307. case ENC_PRESS:
  308. if (record->event.pressed) {
  309. uint16_t mapped_code = handle_encoder_press();
  310. uint16_t held_keycode_timer = timer_read();
  311. if(mapped_code != 0){
  312. register_code16(mapped_code);
  313. while (timer_elapsed(held_keycode_timer) < MEDIA_KEY_DELAY){ /* no-op */ }
  314. unregister_code16(mapped_code);
  315. }
  316. } else {
  317. // Do something else when release
  318. }
  319. return false;
  320. default:
  321. break;
  322. }
  323. #ifdef DYNAMIC_KEYMAP_ENABLE
  324. // Handle macros
  325. if (record->event.pressed) {
  326. if ( keycode >= MACRO00 && keycode <= MACRO15 )
  327. {
  328. uint8_t id = keycode - MACRO00;
  329. dynamic_keymap_macro_send(id);
  330. return false;
  331. }
  332. }
  333. #endif //DYNAMIC_KEYMAP_ENABLE
  334. return process_record_user(keycode, record);
  335. }
  336. void encoder_update_kb(uint8_t index, bool clockwise) {
  337. encoder_value = (encoder_value + (clockwise ? 1 : -1)) % 64;
  338. queue_for_send = true;
  339. if (index == 0) {
  340. if (layer == 0){
  341. uint16_t mapped_code = 0;
  342. if (clockwise) {
  343. mapped_code = handle_encoder_clockwise();
  344. } else {
  345. mapped_code = handle_encoder_ccw();
  346. }
  347. uint16_t held_keycode_timer = timer_read();
  348. if(mapped_code != 0){
  349. register_code16(mapped_code);
  350. while (timer_elapsed(held_keycode_timer) < MEDIA_KEY_DELAY){ /* no-op */ }
  351. unregister_code16(mapped_code);
  352. }
  353. } else {
  354. if(clockwise){
  355. change_encoder_mode(false);
  356. } else {
  357. change_encoder_mode(true);
  358. }
  359. }
  360. }
  361. }
  362. void dynamic_keymap_custom_reset(void){
  363. void *p = (void*)(DYNAMIC_KEYMAP_CUSTOM_BACKLIGHT);
  364. void *end = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR);
  365. while ( p != end ) {
  366. eeprom_update_byte(p, 0);
  367. ++p;
  368. }
  369. eeprom_update_byte((uint8_t*)DYNAMIC_KEYMAP_ENABLED_ENCODER_MODES, 0x1F);
  370. }
  371. void save_backlight_config_to_eeprom(){
  372. eeprom_update_byte((uint8_t*)DYNAMIC_KEYMAP_CUSTOM_BACKLIGHT, kb_backlight_config.raw);
  373. }
  374. void load_custom_config(){
  375. kb_backlight_config.raw = eeprom_read_byte((uint8_t*)DYNAMIC_KEYMAP_CUSTOM_BACKLIGHT);
  376. #ifdef DYNAMIC_KEYMAP_ENABLE
  377. oled_mode = eeprom_read_byte((uint8_t*)DYNAMIC_KEYMAP_DEFAULT_OLED);
  378. enabled_encoder_modes = eeprom_read_byte((uint8_t*)DYNAMIC_KEYMAP_ENABLED_ENCODER_MODES);
  379. #endif
  380. }
  381. void eeprom_init_kb(void)
  382. {
  383. // If the EEPROM has the magic, the data is good.
  384. // OK to load from EEPROM.
  385. if (eeprom_is_valid()) {
  386. load_custom_config();
  387. } else {
  388. // If the EEPROM has not been saved before, or is out of date,
  389. // save the default values to the EEPROM. Default values
  390. // come from construction of the zeal_backlight_config instance.
  391. //backlight_config_save();
  392. #ifdef DYNAMIC_KEYMAP_ENABLE
  393. // This resets the keymaps in EEPROM to what is in flash.
  394. dynamic_keymap_reset();
  395. // This resets the macros in EEPROM to nothing.
  396. dynamic_keymap_macro_reset();
  397. // Reset the custom stuff
  398. dynamic_keymap_custom_reset();
  399. #endif
  400. // Save the magic number last, in case saving was interrupted
  401. eeprom_set_valid(true);
  402. }
  403. }
  404. void matrix_init_kb(void)
  405. {
  406. eeprom_init_kb();
  407. rtcGetTime(&RTCD1, &last_timespec);
  408. queue_for_send = true;
  409. backlight_init_ports();
  410. matrix_init_user();
  411. }
  412. void matrix_scan_kb(void) {
  413. rtcGetTime(&RTCD1, &last_timespec);
  414. uint16_t minutes_since_midnight = last_timespec.millisecond / 1000 / 60;
  415. if (minutes_since_midnight != last_minute){
  416. last_minute = minutes_since_midnight;
  417. if(!oled_sleeping){
  418. queue_for_send = true;
  419. }
  420. }
  421. #ifdef QWIIC_MICRO_OLED_ENABLE
  422. if (queue_for_send && oled_mode != OLED_OFF) {
  423. oled_sleeping = false;
  424. read_host_led_state();
  425. draw_ui();
  426. queue_for_send = false;
  427. }
  428. if (timer_elapsed(last_flush) > ScreenOffInterval && !oled_sleeping) {
  429. send_command(DISPLAYOFF); /* 0xAE */
  430. oled_sleeping = true;
  431. }
  432. #endif
  433. }