satisfaction75.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  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/zeal60/zeal60_api.h" // Temporary hack
  16. #include "keyboards/zeal60/zeal60_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 Zeal60 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. // command_data[2] = 0x00;
  108. // command_data[3] = 0x00;
  109. // command_data[4] = 0x00;
  110. // command_data[5] = 0x00;
  111. // command_data[6] = 0x00;
  112. // command_data[7] = 0x00;
  113. break;
  114. }
  115. default:
  116. {
  117. *command_id = id_unhandled;
  118. break;
  119. }
  120. }
  121. break;
  122. }
  123. #ifdef DYNAMIC_KEYMAP_ENABLE
  124. case id_set_keyboard_value:
  125. {
  126. switch(command_data[0]){
  127. case id_oled_default_mode:
  128. {
  129. eeprom_update_byte((uint8_t*)DYNAMIC_KEYMAP_DEFAULT_OLED, command_data[1]);
  130. break;
  131. }
  132. case id_oled_mode:
  133. {
  134. oled_mode = command_data[1];
  135. draw_ui();
  136. break;
  137. }
  138. case id_encoder_modes:
  139. {
  140. enabled_encoder_modes = command_data[1];
  141. eeprom_update_byte((uint8_t*)DYNAMIC_KEYMAP_ENABLED_ENCODER_MODES, enabled_encoder_modes);
  142. break;
  143. }
  144. case id_encoder_custom:
  145. {
  146. // uint8_t custom_encoder_idx = command_data[1];
  147. break;
  148. }
  149. default:
  150. {
  151. *command_id = id_unhandled;
  152. break;
  153. }
  154. }
  155. break;
  156. }
  157. case id_dynamic_keymap_get_keycode:
  158. {
  159. uint16_t keycode = dynamic_keymap_get_keycode( command_data[0], command_data[1], command_data[2] );
  160. command_data[3] = keycode >> 8;
  161. command_data[4] = keycode & 0xFF;
  162. break;
  163. }
  164. case id_dynamic_keymap_set_keycode:
  165. {
  166. dynamic_keymap_set_keycode( command_data[0], command_data[1], command_data[2], ( command_data[3] << 8 ) | command_data[4] );
  167. break;
  168. }
  169. case id_dynamic_keymap_reset:
  170. {
  171. dynamic_keymap_reset();
  172. break;
  173. }
  174. case id_dynamic_keymap_macro_get_count:
  175. {
  176. command_data[0] = dynamic_keymap_macro_get_count();
  177. break;
  178. }
  179. case id_dynamic_keymap_macro_get_buffer_size:
  180. {
  181. uint16_t size = dynamic_keymap_macro_get_buffer_size();
  182. command_data[0] = size >> 8;
  183. command_data[1] = size & 0xFF;
  184. break;
  185. }
  186. case id_dynamic_keymap_macro_get_buffer:
  187. {
  188. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  189. uint16_t size = command_data[2]; // size <= 28
  190. dynamic_keymap_macro_get_buffer( offset, size, &command_data[3] );
  191. break;
  192. }
  193. case id_dynamic_keymap_macro_set_buffer:
  194. {
  195. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  196. uint16_t size = command_data[2]; // size <= 28
  197. dynamic_keymap_macro_set_buffer( offset, size, &command_data[3] );
  198. break;
  199. }
  200. case id_dynamic_keymap_macro_reset:
  201. {
  202. dynamic_keymap_macro_reset();
  203. break;
  204. }
  205. case id_dynamic_keymap_get_layer_count:
  206. {
  207. command_data[0] = dynamic_keymap_get_layer_count();
  208. break;
  209. }
  210. case id_dynamic_keymap_get_buffer:
  211. {
  212. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  213. uint16_t size = command_data[2]; // size <= 28
  214. dynamic_keymap_get_buffer( offset, size, &command_data[3] );
  215. break;
  216. }
  217. case id_dynamic_keymap_set_buffer:
  218. {
  219. uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
  220. uint16_t size = command_data[2]; // size <= 28
  221. dynamic_keymap_set_buffer( offset, size, &command_data[3] );
  222. break;
  223. }
  224. #endif // DYNAMIC_KEYMAP_ENABLE
  225. case id_eeprom_reset:
  226. {
  227. eeprom_reset();
  228. break;
  229. }
  230. case id_bootloader_jump:
  231. {
  232. // Need to send data back before the jump
  233. // Informs host that the command is handled
  234. raw_hid_send( data, length );
  235. // Give host time to read it
  236. wait_ms(100);
  237. bootloader_jump();
  238. break;
  239. }
  240. default:
  241. {
  242. // Unhandled message.
  243. *command_id = id_unhandled;
  244. break;
  245. }
  246. }
  247. // Return same buffer with values changed
  248. raw_hid_send( data, length );
  249. }
  250. #endif
  251. void read_host_led_state(void) {
  252. uint8_t leds = host_keyboard_leds();
  253. if (leds & (1 << USB_LED_NUM_LOCK)) {
  254. if (led_numlock == false){
  255. led_numlock = true;}
  256. } else {
  257. if (led_numlock == true){
  258. led_numlock = false;}
  259. }
  260. if (leds & (1 << USB_LED_CAPS_LOCK)) {
  261. if (led_capslock == false){
  262. led_capslock = true;}
  263. } else {
  264. if (led_capslock == true){
  265. led_capslock = false;}
  266. }
  267. if (leds & (1 << USB_LED_SCROLL_LOCK)) {
  268. if (led_scrolllock == false){
  269. led_scrolllock = true;}
  270. } else {
  271. if (led_scrolllock == true){
  272. led_scrolllock = false;}
  273. }
  274. }
  275. uint32_t layer_state_set_kb(uint32_t state) {
  276. state = layer_state_set_user(state);
  277. layer = biton32(state);
  278. queue_for_send = true;
  279. return state;
  280. }
  281. bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
  282. queue_for_send = true;
  283. switch (keycode) {
  284. case OLED_TOGG:
  285. if(!clock_set_mode){
  286. if (record->event.pressed) {
  287. oled_mode = (oled_mode + 1) % _NUM_OLED_MODES;
  288. draw_ui();
  289. }
  290. }
  291. return false;
  292. case CLOCK_SET:
  293. if (record->event.pressed) {
  294. if(clock_set_mode){
  295. pre_encoder_mode_change();
  296. clock_set_mode = false;
  297. encoder_mode = previous_encoder_mode;
  298. post_encoder_mode_change();
  299. }else{
  300. previous_encoder_mode = encoder_mode;
  301. pre_encoder_mode_change();
  302. clock_set_mode = true;
  303. encoder_mode = ENC_MODE_CLOCK_SET;
  304. post_encoder_mode_change();
  305. }
  306. }
  307. return false;
  308. case ENC_PRESS:
  309. if (record->event.pressed) {
  310. uint16_t mapped_code = handle_encoder_press();
  311. uint16_t held_keycode_timer = timer_read();
  312. if(mapped_code != 0){
  313. register_code(mapped_code);
  314. while (timer_elapsed(held_keycode_timer) < MEDIA_KEY_DELAY){ /* no-op */ }
  315. unregister_code(mapped_code);
  316. }
  317. } else {
  318. // Do something else when release
  319. }
  320. return false;
  321. default:
  322. break;
  323. }
  324. #ifdef DYNAMIC_KEYMAP_ENABLE
  325. // Handle macros
  326. if (record->event.pressed) {
  327. if ( keycode >= MACRO00 && keycode <= MACRO15 )
  328. {
  329. uint8_t id = keycode - MACRO00;
  330. dynamic_keymap_macro_send(id);
  331. return false;
  332. }
  333. }
  334. #endif //DYNAMIC_KEYMAP_ENABLE
  335. return process_record_user(keycode, record);
  336. }
  337. void encoder_update_kb(uint8_t index, bool clockwise) {
  338. encoder_value = (encoder_value + (clockwise ? 1 : -1)) % 64;
  339. queue_for_send = true;
  340. if (index == 0) {
  341. if (layer == 0){
  342. uint16_t mapped_code = 0;
  343. if (clockwise) {
  344. mapped_code = handle_encoder_clockwise();
  345. } else {
  346. mapped_code = handle_encoder_ccw();
  347. }
  348. uint16_t held_keycode_timer = timer_read();
  349. if(mapped_code != 0){
  350. register_code(mapped_code);
  351. while (timer_elapsed(held_keycode_timer) < MEDIA_KEY_DELAY){ /* no-op */ }
  352. unregister_code(mapped_code);
  353. }
  354. } else {
  355. if(clockwise){
  356. change_encoder_mode(false);
  357. } else {
  358. change_encoder_mode(true);
  359. }
  360. }
  361. }
  362. }
  363. void dynamic_keymap_custom_reset(void){
  364. void *p = (void*)(DYNAMIC_KEYMAP_CUSTOM_BACKLIGHT);
  365. void *end = (void*)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR);
  366. while ( p != end ) {
  367. eeprom_update_byte(p, 0);
  368. ++p;
  369. }
  370. eeprom_update_byte((uint8_t*)DYNAMIC_KEYMAP_ENABLED_ENCODER_MODES, 0x1F);
  371. }
  372. void save_backlight_config_to_eeprom(){
  373. eeprom_update_byte((uint8_t*)DYNAMIC_KEYMAP_CUSTOM_BACKLIGHT, kb_backlight_config.raw);
  374. }
  375. void load_custom_config(){
  376. kb_backlight_config.raw = eeprom_read_byte((uint8_t*)DYNAMIC_KEYMAP_CUSTOM_BACKLIGHT);
  377. #ifdef DYNAMIC_KEYMAP_ENABLE
  378. oled_mode = eeprom_read_byte((uint8_t*)DYNAMIC_KEYMAP_DEFAULT_OLED);
  379. enabled_encoder_modes = eeprom_read_byte((uint8_t*)DYNAMIC_KEYMAP_ENABLED_ENCODER_MODES);
  380. #endif
  381. }
  382. void eeprom_init_kb(void)
  383. {
  384. // If the EEPROM has the magic, the data is good.
  385. // OK to load from EEPROM.
  386. if (eeprom_is_valid()) {
  387. load_custom_config();
  388. } else {
  389. // If the EEPROM has not been saved before, or is out of date,
  390. // save the default values to the EEPROM. Default values
  391. // come from construction of the zeal_backlight_config instance.
  392. //backlight_config_save();
  393. #ifdef DYNAMIC_KEYMAP_ENABLE
  394. // This resets the keymaps in EEPROM to what is in flash.
  395. dynamic_keymap_reset();
  396. // This resets the macros in EEPROM to nothing.
  397. dynamic_keymap_macro_reset();
  398. // Reset the custom stuff
  399. dynamic_keymap_custom_reset();
  400. #endif
  401. // Save the magic number last, in case saving was interrupted
  402. eeprom_set_valid(true);
  403. }
  404. }
  405. void matrix_init_kb(void)
  406. {
  407. eeprom_init_kb();
  408. rtcGetTime(&RTCD1, &last_timespec);
  409. queue_for_send = true;
  410. backlight_init_ports();
  411. matrix_init_user();
  412. }
  413. void matrix_scan_kb(void) {
  414. rtcGetTime(&RTCD1, &last_timespec);
  415. uint16_t minutes_since_midnight = last_timespec.millisecond / 1000 / 60;
  416. if (minutes_since_midnight != last_minute){
  417. last_minute = minutes_since_midnight;
  418. if(!oled_sleeping){
  419. queue_for_send = true;
  420. }
  421. }
  422. #ifdef QWIIC_MICRO_OLED_ENABLE
  423. if (queue_for_send && oled_mode != OLED_OFF) {
  424. oled_sleeping = false;
  425. read_host_led_state();
  426. draw_ui();
  427. queue_for_send = false;
  428. }
  429. if (timer_elapsed(last_flush) > ScreenOffInterval && !oled_sleeping) {
  430. send_command(DISPLAYOFF); /* 0xAE */
  431. oled_sleeping = true;
  432. }
  433. #endif
  434. }