bbaserdem.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /* Copyright 2021 Batuhan Başerdem
  2. * <baserdem.batuhan@gmail.com> @bbaserdem
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "bbaserdem.h"
  18. // Language imports
  19. #include <sendstring_dvorak.h>
  20. // Need memcpy and memcmp from string.h along with transfer stuff
  21. #ifdef SPLIT_KEYBOARD
  22. #include "transactions.h"
  23. #include <string.h>
  24. #endif // SPLIT_KEYBOARD
  25. /*-------------------------*\
  26. |*-----KEYBOARD CONFIG-----*|
  27. \*-------------------------*/
  28. userspace_config_t userspace_config;
  29. userspace_runtime_t userspace_runtime;
  30. /*---------------------------------*\
  31. |*----SPLIT KEYBOARD TRANSPORT-----*|
  32. \*---------------------------------*/
  33. #ifdef SPLIT_KEYBOARD
  34. userspace_config_t transport_userspace_config;
  35. userspace_runtime_t transport_userspace_runtime;
  36. // Translate the RPC data to the local variable
  37. void userspace_config_sync(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) {
  38. // Copy incoming data to local variable
  39. if (in_buflen == sizeof(transport_userspace_config)) {
  40. memcpy(&transport_userspace_config, in_data, in_buflen);
  41. }
  42. // There is no data to send back; so no output handling
  43. }
  44. void userspace_runtime_sync(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) {
  45. // Copy incoming data to local variable
  46. if (in_buflen == sizeof(transport_userspace_runtime)) {
  47. memcpy(&transport_userspace_runtime, in_data, in_buflen);
  48. }
  49. // There is no data to send back; so no output handling
  50. }
  51. // Either send or receive the correct data
  52. void userspace_transport_update(void) {
  53. if (is_keyboard_master()) {
  54. // If we are the main device; we want to send info.
  55. transport_userspace_config.raw = userspace_config.raw;
  56. transport_userspace_runtime.raw = userspace_runtime.raw;
  57. } else {
  58. // If we are the secondary device; we want to receive info, and save to eeprom.
  59. userspace_config.raw = transport_userspace_config.raw;
  60. userspace_runtime.raw = transport_userspace_runtime.raw;
  61. }
  62. }
  63. // Initiate the protocol on sync
  64. void userspace_transport_sync(bool force_sync) {
  65. if (is_keyboard_master()) {
  66. // Keep track of the last state
  67. static userspace_config_t last_userspace_config;
  68. static userspace_runtime_t last_userspace_runtime;
  69. bool needs_sync = false;
  70. // Check if the config values are different
  71. if (memcmp(&transport_userspace_config, &last_userspace_config, sizeof(transport_userspace_config))) {
  72. needs_sync = true;
  73. memcpy(&last_userspace_config, &transport_userspace_config, sizeof(transport_userspace_config));
  74. }
  75. // Perform the sync if requested
  76. if (needs_sync || force_sync) {
  77. transaction_rpc_send(RPC_ID_CONFIG_SYNC, sizeof(transport_userspace_config), &transport_userspace_config);
  78. needs_sync = false;
  79. }
  80. // Check if the runtime values are different
  81. if (memcmp(&transport_userspace_runtime, &last_userspace_runtime, sizeof(transport_userspace_runtime))) {
  82. needs_sync = true;
  83. memcpy(&last_userspace_runtime, &transport_userspace_runtime, sizeof(transport_userspace_runtime));
  84. }
  85. // Perform the sync if requested
  86. if (needs_sync || force_sync) {
  87. transaction_rpc_send(RPC_ID_RUNTIME_SYNC, sizeof(transport_userspace_runtime), &transport_userspace_runtime);
  88. needs_sync = false;
  89. }
  90. }
  91. }
  92. #endif // SPLIT_KEYBOARD
  93. /*---------------------------*\
  94. |*-----KEYBOARD PRE INIT-----*|
  95. \*---------------------------*/
  96. /* This code runs before anything is started.
  97. * Good for early hardware setup
  98. */
  99. __attribute__ ((weak)) void keyboard_pre_init_keymap(void) {}
  100. __attribute__ ((weak)) void keyboard_pre_init_user(void) {
  101. // Keymap specific stuff
  102. keyboard_pre_init_keymap();
  103. }
  104. /*---------------------*\
  105. |*-----MATRIX INIT-----*|
  106. \*---------------------*/
  107. /* This code runs once midway thru the firmware process.
  108. * So far, sets the base layer and fixes unicode mode
  109. */
  110. __attribute__ ((weak)) void matrix_init_keymap(void) {}
  111. void matrix_init_user (void) {
  112. // Keymap specific things
  113. matrix_init_keymap();
  114. }
  115. /*----------------------------*\
  116. |*-----KEYBOARD POST INIT-----*|
  117. \*----------------------------*/
  118. /* This code runs after anything is started.
  119. * Good for late hardware setup, like setting up layer specifications
  120. */
  121. __attribute__ ((weak)) void keyboard_post_init_keymap(void) {}
  122. __attribute__ ((weak)) void keyboard_post_init_user(void) {
  123. // Fix beginning base layer, in case some other firmware was flashed
  124. // set_single_persistent_default_layer(_BASE);
  125. // Unicode mode
  126. # ifdef UNICODEMAP_ENABLE
  127. set_unicode_input_mode(UC_LNX);
  128. # endif // UNICODEMAP_ENABLE
  129. // Split keyboard halves communication
  130. # ifdef SPLIT_KEYBOARD
  131. // Register the transactions
  132. transaction_register_rpc( RPC_ID_CONFIG_SYNC, userspace_config_sync );
  133. transaction_register_rpc(RPC_ID_RUNTIME_SYNC, userspace_runtime_sync);
  134. // Load default config values
  135. if (is_keyboard_master()) {
  136. // If we are main; load from eeconfig
  137. userspace_config.raw = eeconfig_read_user();
  138. // And update the transport variable
  139. userspace_transport_update();
  140. // Do one forced transfer to sync halves
  141. userspace_transport_sync(true);
  142. } else {
  143. // Just sync the data received
  144. userspace_transport_update();
  145. }
  146. # else // SPLIT_KEYBOARD
  147. // If we are not split; just load from eeprom
  148. userspace_config.raw = eeconfig_read_user();
  149. # endif // SPLIT_KEYBOARD
  150. // Backlight LED
  151. # ifdef BACKLIGHT_ENABLE
  152. keyboard_post_init_backlight();
  153. # endif // BACKLIGHT_ENABLE
  154. // RGB underglow
  155. # ifdef RGBLIGHT_ENABLE
  156. keyboard_post_init_underglow();
  157. # endif // RGBLIGHT_ENABLE
  158. // Keymap specific stuff
  159. keyboard_post_init_keymap();
  160. }
  161. /*---------------------------*\
  162. |*-----HOUSEKEEPING TASK-----*|
  163. \*---------------------------*/
  164. /* I have no idea what this does
  165. */
  166. __attribute__ ((weak)) void housekeeping_task_keymap(void) {}
  167. void housekeeping_task_user(void) {
  168. // Check eeprom every now and then
  169. static userspace_config_t prev_userspace_config;
  170. static fast_timer_t throttle_timer = 0;
  171. static bool init_flag = true;
  172. // Read this if we never read it before
  173. if (init_flag) {
  174. init_flag = false;
  175. prev_userspace_config.raw = eeconfig_read_user();
  176. }
  177. // Throttled tasks here
  178. if (timer_elapsed_fast(throttle_timer) >= HOUSEKEEPING_THROTTLE_INTERVAL_MS) {
  179. // Refresh timer
  180. throttle_timer = timer_read_fast();
  181. // Check userspace config for eeprom updates
  182. if (memcmp(&prev_userspace_config, &userspace_config, sizeof(userspace_config))) {
  183. memcpy(&prev_userspace_config, &userspace_config, sizeof(userspace_config));
  184. eeconfig_update_user(userspace_config.raw);
  185. }
  186. }
  187. // Do transport stuff
  188. # ifdef SPLIT_KEYBOARD
  189. userspace_transport_update();
  190. userspace_transport_sync(false);
  191. # endif // SPLIT_KEYBOARD
  192. // Hook to keymap code
  193. housekeeping_task_keymap();
  194. }
  195. /*-----------------------*\
  196. |*-----EECONFIG INIT-----*|
  197. \*-----------------------*/
  198. /* Default values to send to the eeprom
  199. */
  200. void eeconfig_init_user(void) {
  201. // Set everything to default
  202. userspace_config.raw = 0;
  203. // Set encoder states to sane defaults if enabled
  204. # ifdef ENCODER_ENABLE
  205. reset_encoder_state();
  206. # endif // ENCODER_ENABLE
  207. }
  208. /*------------------------*\
  209. |*-----PROCESS RECORD-----*|
  210. \*------------------------*/
  211. /* Process record: custom keycodes to process here
  212. * Allow also the following codes to hook here as well;
  213. * Macro definitions
  214. * Audio hooks
  215. */
  216. __attribute__ ((weak))
  217. bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
  218. return true;
  219. }
  220. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  221. // Return after running through all individual hooks
  222. return
  223. process_record_keymap(keycode, record) &&
  224. # ifdef AUDIO_ENABLE
  225. process_record_audio(keycode, record) &&
  226. # endif // AUDIO_ENABLE
  227. # ifdef ENCODER_ENABLE
  228. process_record_encoder(keycode, record) &&
  229. # endif // ENCODER_ENABLE
  230. process_record_macro(keycode, record);
  231. }
  232. /*---------------------*\
  233. |*-----MATRIX SCAN-----*|
  234. \*---------------------*/
  235. /* This code runs every frame
  236. * I used to check for layer switching here, but layer state is better used.
  237. * Try to not put anything here; as it runs hundreds time per second-ish
  238. */
  239. __attribute__ ((weak)) void matrix_scan_keymap(void) { }
  240. void matrix_scan_user (void) {
  241. // Keymap specific scan function
  242. matrix_scan_keymap();
  243. }
  244. /*---------------------*\
  245. |*-----LAYER STATE-----*|
  246. \*---------------------*/
  247. /* This code runs after every layer change
  248. * State represents the new layer state.
  249. */
  250. __attribute__ ((weak))
  251. layer_state_t layer_state_set_keymap (layer_state_t state) {
  252. return state;
  253. }
  254. layer_state_t layer_state_set_user(layer_state_t state) {
  255. // Keymap layer state setting
  256. state = layer_state_set_keymap(state);
  257. // For underglow stuff
  258. # ifdef RGBLIGHT_ENABLE
  259. state = layer_state_set_underglow(state);
  260. # endif // RGBLIGHT_ENABLE
  261. // Audio playback
  262. # ifdef AUDIO_ENABLE
  263. state = layer_state_set_audio(state);
  264. # endif // AUDIO_ENABLE
  265. return state;
  266. }
  267. /*-----------------------------*\
  268. |*-----DEFAULT LAYER STATE-----*|
  269. \*-----------------------------*/
  270. /* This code runs after every time default base layer is changed
  271. */
  272. __attribute__ ((weak))
  273. layer_state_t default_layer_state_set_keymap (layer_state_t state) {
  274. return state;
  275. }
  276. layer_state_t default_layer_state_set_user(layer_state_t state) {
  277. // Keymap level code
  278. state = default_layer_state_set_keymap(state);
  279. return state;
  280. }
  281. /*------------------------*\
  282. |*-----LED SET KEYMAP-----*|
  283. \*------------------------*/
  284. /* Code for LED indicators
  285. * I'm not sure when exactly does this code run
  286. */
  287. __attribute__ ((weak)) void led_set_keymap(uint8_t usb_led) {}
  288. void led_set_user(uint8_t usb_led) {
  289. led_set_keymap(usb_led);
  290. }
  291. /*-----------------*\
  292. |*-----SUSPEND-----*|
  293. \*-----------------*/
  294. /* Suspend stuff here, mostly for the rgb lighting.
  295. */
  296. __attribute__ ((weak)) void suspend_power_down_keymap (void) { }
  297. void suspend_power_down_user(void) {
  298. suspend_power_down_keymap();
  299. // RGB matrix sleep hook
  300. # ifdef RGB_MATRIX_ENABLE
  301. suspend_power_down_rgb();
  302. # endif // RGB_MATRIX_ENABLE
  303. }
  304. __attribute__ ((weak)) void suspend_wakeup_init_keymap (void) { }
  305. void suspend_wakeup_init_user(void) {
  306. suspend_wakeup_init_keymap();
  307. // RGB matrix sleep hook
  308. # ifdef RGB_MATRIX_ENABLE
  309. suspend_wakeup_init_rgb();
  310. # endif // RGB_MATRIX_ENABLE
  311. }
  312. <<<<<<< HEAD
  313. state = layer_state_set_keymap (state);
  314. #ifdef RGBLIGHT_ENABLE
  315. // Change RGB lighting depending on the last layer activated
  316. rgblight_change( get_highest_layer(state) );
  317. #endif
  318. return state;
  319. ||||||| f439fe6055
  320. state = layer_state_set_keymap (state);
  321. #ifdef RGBLIGHT_ENABLE
  322. // Change RGB lighting depending on the last layer activated
  323. rgblight_change( biton32(state) );
  324. #endif
  325. return state;
  326. =======
  327. /*------------------*\
  328. |*-----SHUTDOWN-----*|
  329. \*------------------*/
  330. /* Shutdown stuff here; for when entering bootmode.
  331. */
  332. __attribute__ ((weak)) void shutdown_keymap (void) { }
  333. void shutdown_user(void) {
  334. // Underglow LED hook on boot
  335. # ifdef RGBLIGHT_ENABLE
  336. shutdown_underglow();
  337. # endif // RGBLIGHT_ENABLE
  338. // Perkey led hook on boot
  339. # ifdef RGB_MATRIX_ENABLE
  340. shutdown_rgb();
  341. # endif // RGB_MATRIX_ENABLE
  342. // Keymap hooks
  343. shutdown_keymap();
  344. >>>>>>> upstream/master
  345. }