123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- /* Copyright 2021 Batuhan Başerdem
- * <baserdem.batuhan@gmail.com> @bbaserdem
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "bbaserdem.h"
- // Language imports
- #include <sendstring_dvorak.h>
- // Need memcpy and memcmp from string.h along with transfer stuff
- #ifdef SPLIT_KEYBOARD
- #include "transactions.h"
- #include <string.h>
- #endif // SPLIT_KEYBOARD
- /*-------------------------*\
- |*-----KEYBOARD CONFIG-----*|
- \*-------------------------*/
- userspace_config_t userspace_config;
- userspace_runtime_t userspace_runtime;
- /*---------------------------------*\
- |*----SPLIT KEYBOARD TRANSPORT-----*|
- \*---------------------------------*/
- #ifdef SPLIT_KEYBOARD
- userspace_config_t transport_userspace_config;
- userspace_runtime_t transport_userspace_runtime;
- // Translate the RPC data to the local variable
- void userspace_config_sync(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) {
- // Copy incoming data to local variable
- if (in_buflen == sizeof(transport_userspace_config)) {
- memcpy(&transport_userspace_config, in_data, in_buflen);
- }
- // There is no data to send back; so no output handling
- }
- void userspace_runtime_sync(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) {
- // Copy incoming data to local variable
- if (in_buflen == sizeof(transport_userspace_runtime)) {
- memcpy(&transport_userspace_runtime, in_data, in_buflen);
- }
- // There is no data to send back; so no output handling
- }
- // Either send or receive the correct data
- void userspace_transport_update(void) {
- if (is_keyboard_master()) {
- // If we are the main device; we want to send info.
- transport_userspace_config.raw = userspace_config.raw;
- transport_userspace_runtime.raw = userspace_runtime.raw;
- } else {
- // If we are the secondary device; we want to receive info, and save to eeprom.
- userspace_config.raw = transport_userspace_config.raw;
- userspace_runtime.raw = transport_userspace_runtime.raw;
- }
- }
- // Initiate the protocol on sync
- void userspace_transport_sync(bool force_sync) {
- if (is_keyboard_master()) {
- // Keep track of the last state
- static userspace_config_t last_userspace_config;
- static userspace_runtime_t last_userspace_runtime;
- bool needs_sync = false;
- // Check if the config values are different
- if (memcmp(&transport_userspace_config, &last_userspace_config, sizeof(transport_userspace_config))) {
- needs_sync = true;
- memcpy(&last_userspace_config, &transport_userspace_config, sizeof(transport_userspace_config));
- }
- // Perform the sync if requested
- if (needs_sync || force_sync) {
- transaction_rpc_send(RPC_ID_CONFIG_SYNC, sizeof(transport_userspace_config), &transport_userspace_config);
- needs_sync = false;
- }
- // Check if the runtime values are different
- if (memcmp(&transport_userspace_runtime, &last_userspace_runtime, sizeof(transport_userspace_runtime))) {
- needs_sync = true;
- memcpy(&last_userspace_runtime, &transport_userspace_runtime, sizeof(transport_userspace_runtime));
- }
- // Perform the sync if requested
- if (needs_sync || force_sync) {
- transaction_rpc_send(RPC_ID_RUNTIME_SYNC, sizeof(transport_userspace_runtime), &transport_userspace_runtime);
- needs_sync = false;
- }
- }
- }
- #endif // SPLIT_KEYBOARD
- /*---------------------------*\
- |*-----KEYBOARD PRE INIT-----*|
- \*---------------------------*/
- /* This code runs before anything is started.
- * Good for early hardware setup
- */
- __attribute__ ((weak)) void keyboard_pre_init_keymap(void) {}
- __attribute__ ((weak)) void keyboard_pre_init_user(void) {
- // Keymap specific stuff
- keyboard_pre_init_keymap();
- }
- /*---------------------*\
- |*-----MATRIX INIT-----*|
- \*---------------------*/
- /* This code runs once midway thru the firmware process.
- * So far, sets the base layer and fixes unicode mode
- */
- __attribute__ ((weak)) void matrix_init_keymap(void) {}
- void matrix_init_user (void) {
- // Keymap specific things
- matrix_init_keymap();
- }
- /*----------------------------*\
- |*-----KEYBOARD POST INIT-----*|
- \*----------------------------*/
- /* This code runs after anything is started.
- * Good for late hardware setup, like setting up layer specifications
- */
- __attribute__ ((weak)) void keyboard_post_init_keymap(void) {}
- __attribute__ ((weak)) void keyboard_post_init_user(void) {
- // Fix beginning base layer, in case some other firmware was flashed
- // set_single_persistent_default_layer(_BASE);
- // Unicode mode
- # ifdef UNICODEMAP_ENABLE
- set_unicode_input_mode(UC_LNX);
- # endif // UNICODEMAP_ENABLE
- // Split keyboard halves communication
- # ifdef SPLIT_KEYBOARD
- // Register the transactions
- transaction_register_rpc( RPC_ID_CONFIG_SYNC, userspace_config_sync );
- transaction_register_rpc(RPC_ID_RUNTIME_SYNC, userspace_runtime_sync);
- // Load default config values
- if (is_keyboard_master()) {
- // If we are main; load from eeconfig
- userspace_config.raw = eeconfig_read_user();
- // And update the transport variable
- userspace_transport_update();
- // Do one forced transfer to sync halves
- userspace_transport_sync(true);
- } else {
- // Just sync the data received
- userspace_transport_update();
- }
- # else // SPLIT_KEYBOARD
- // If we are not split; just load from eeprom
- userspace_config.raw = eeconfig_read_user();
- # endif // SPLIT_KEYBOARD
- // Backlight LED
- # ifdef BACKLIGHT_ENABLE
- keyboard_post_init_backlight();
- # endif // BACKLIGHT_ENABLE
- // RGB underglow
- # ifdef RGBLIGHT_ENABLE
- keyboard_post_init_underglow();
- # endif // RGBLIGHT_ENABLE
- // Keymap specific stuff
- keyboard_post_init_keymap();
- }
- /*---------------------------*\
- |*-----HOUSEKEEPING TASK-----*|
- \*---------------------------*/
- /* I have no idea what this does
- */
- __attribute__ ((weak)) void housekeeping_task_keymap(void) {}
- void housekeeping_task_user(void) {
- // Check eeprom every now and then
- static userspace_config_t prev_userspace_config;
- static fast_timer_t throttle_timer = 0;
- static bool init_flag = true;
- // Read this if we never read it before
- if (init_flag) {
- init_flag = false;
- prev_userspace_config.raw = eeconfig_read_user();
- }
- // Throttled tasks here
- if (timer_elapsed_fast(throttle_timer) >= HOUSEKEEPING_THROTTLE_INTERVAL_MS) {
- // Refresh timer
- throttle_timer = timer_read_fast();
- // Check userspace config for eeprom updates
- if (memcmp(&prev_userspace_config, &userspace_config, sizeof(userspace_config))) {
- memcpy(&prev_userspace_config, &userspace_config, sizeof(userspace_config));
- eeconfig_update_user(userspace_config.raw);
- }
- }
- // Do transport stuff
- # ifdef SPLIT_KEYBOARD
- userspace_transport_update();
- userspace_transport_sync(false);
- # endif // SPLIT_KEYBOARD
- // Hook to keymap code
- housekeeping_task_keymap();
- }
- /*-----------------------*\
- |*-----EECONFIG INIT-----*|
- \*-----------------------*/
- /* Default values to send to the eeprom
- */
- void eeconfig_init_user(void) {
- // Set everything to default
- userspace_config.raw = 0;
- // Set encoder states to sane defaults if enabled
- # ifdef ENCODER_ENABLE
- reset_encoder_state();
- # endif // ENCODER_ENABLE
- }
- /*------------------------*\
- |*-----PROCESS RECORD-----*|
- \*------------------------*/
- /* Process record: custom keycodes to process here
- * Allow also the following codes to hook here as well;
- * Macro definitions
- * Audio hooks
- */
- __attribute__ ((weak))
- bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
- return true;
- }
- bool process_record_user(uint16_t keycode, keyrecord_t *record) {
- // Return after running through all individual hooks
- return
- process_record_keymap(keycode, record) &&
- # ifdef AUDIO_ENABLE
- process_record_audio(keycode, record) &&
- # endif // AUDIO_ENABLE
- # ifdef ENCODER_ENABLE
- process_record_encoder(keycode, record) &&
- # endif // ENCODER_ENABLE
- process_record_macro(keycode, record);
- }
- /*---------------------*\
- |*-----MATRIX SCAN-----*|
- \*---------------------*/
- /* This code runs every frame
- * I used to check for layer switching here, but layer state is better used.
- * Try to not put anything here; as it runs hundreds time per second-ish
- */
- __attribute__ ((weak)) void matrix_scan_keymap(void) { }
- void matrix_scan_user (void) {
- // Keymap specific scan function
- matrix_scan_keymap();
- }
- /*---------------------*\
- |*-----LAYER STATE-----*|
- \*---------------------*/
- /* This code runs after every layer change
- * State represents the new layer state.
- */
- __attribute__ ((weak))
- layer_state_t layer_state_set_keymap (layer_state_t state) {
- return state;
- }
- layer_state_t layer_state_set_user(layer_state_t state) {
- // Keymap layer state setting
- state = layer_state_set_keymap(state);
- // For underglow stuff
- # ifdef RGBLIGHT_ENABLE
- state = layer_state_set_underglow(state);
- # endif // RGBLIGHT_ENABLE
- // Audio playback
- # ifdef AUDIO_ENABLE
- state = layer_state_set_audio(state);
- # endif // AUDIO_ENABLE
- return state;
- }
- /*-----------------------------*\
- |*-----DEFAULT LAYER STATE-----*|
- \*-----------------------------*/
- /* This code runs after every time default base layer is changed
- */
- __attribute__ ((weak))
- layer_state_t default_layer_state_set_keymap (layer_state_t state) {
- return state;
- }
- layer_state_t default_layer_state_set_user(layer_state_t state) {
- // Keymap level code
- state = default_layer_state_set_keymap(state);
- return state;
- }
- /*------------------------*\
- |*-----LED SET KEYMAP-----*|
- \*------------------------*/
- /* Code for LED indicators
- * I'm not sure when exactly does this code run
- */
- __attribute__ ((weak)) void led_set_keymap(uint8_t usb_led) {}
- void led_set_user(uint8_t usb_led) {
- led_set_keymap(usb_led);
- }
- /*-----------------*\
- |*-----SUSPEND-----*|
- \*-----------------*/
- /* Suspend stuff here, mostly for the rgb lighting.
- */
- __attribute__ ((weak)) void suspend_power_down_keymap (void) { }
- void suspend_power_down_user(void) {
- suspend_power_down_keymap();
- // RGB matrix sleep hook
- # ifdef RGB_MATRIX_ENABLE
- suspend_power_down_rgb();
- # endif // RGB_MATRIX_ENABLE
- }
- __attribute__ ((weak)) void suspend_wakeup_init_keymap (void) { }
- void suspend_wakeup_init_user(void) {
- suspend_wakeup_init_keymap();
- // RGB matrix sleep hook
- # ifdef RGB_MATRIX_ENABLE
- suspend_wakeup_init_rgb();
- # endif // RGB_MATRIX_ENABLE
- }
- <<<<<<< HEAD
- state = layer_state_set_keymap (state);
- #ifdef RGBLIGHT_ENABLE
- // Change RGB lighting depending on the last layer activated
- rgblight_change( get_highest_layer(state) );
- #endif
- return state;
- ||||||| f439fe6055
- state = layer_state_set_keymap (state);
- #ifdef RGBLIGHT_ENABLE
- // Change RGB lighting depending on the last layer activated
- rgblight_change( biton32(state) );
- #endif
- return state;
- =======
- /*------------------*\
- |*-----SHUTDOWN-----*|
- \*------------------*/
- /* Shutdown stuff here; for when entering bootmode.
- */
- __attribute__ ((weak)) void shutdown_keymap (void) { }
- void shutdown_user(void) {
- // Underglow LED hook on boot
- # ifdef RGBLIGHT_ENABLE
- shutdown_underglow();
- # endif // RGBLIGHT_ENABLE
- // Perkey led hook on boot
- # ifdef RGB_MATRIX_ENABLE
- shutdown_rgb();
- # endif // RGB_MATRIX_ENABLE
- // Keymap hooks
- shutdown_keymap();
- >>>>>>> upstream/master
- }
|