Drashna's split updates (#13350)
Co-authored-by: Ryan <fauxpark@gmail.com>
This commit is contained in:
		
							parent
							
								
									bbe45185e3
								
							
						
					
					
						commit
						b7cf9a888a
					
				
					 54 changed files with 1889 additions and 1819 deletions
				
			
		| 
						 | 
				
			
			@ -17,34 +17,49 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
// Use custom magic number so that when switching branches, EEPROM always gets reset
 | 
			
		||||
#define EECONFIG_MAGIC_NUMBER (uint16_t)0x1339
 | 
			
		||||
#define EECONFIG_MAGIC_NUMBER   (uint16_t)0x1339
 | 
			
		||||
 | 
			
		||||
/* Set Polling rate to 1000Hz */
 | 
			
		||||
#define USB_POLLING_INTERVAL_MS 1
 | 
			
		||||
 | 
			
		||||
#if defined(SPLIT_KEYBOARD)
 | 
			
		||||
#    define SPLIT_MODS_ENABLE
 | 
			
		||||
#    define SPLIT_TRANSPORT_MIRROR
 | 
			
		||||
#    define SPLIT_LAYER_STATE_ENABLE
 | 
			
		||||
#    define SPLIT_LED_STATE_ENABLE
 | 
			
		||||
 | 
			
		||||
// #    define SPLIT_TRANSPORT_MIRROR
 | 
			
		||||
#    define SERIAL_USE_MULTI_TRANSACTION
 | 
			
		||||
// #    define SPLIT_NUM_TRANSACTIONS_KB 2
 | 
			
		||||
#    define SPLIT_TRANSACTION_IDS_USER RPC_ID_USER_STATE_SYNC
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef AUDIO_ENABLE
 | 
			
		||||
 | 
			
		||||
#    define AUDIO_CLICKY
 | 
			
		||||
#    define STARTUP_SONG SONG(RICK_ROLL)
 | 
			
		||||
#    define GOODBYE_SONG SONG(SONIC_RING)
 | 
			
		||||
#    define DEFAULT_LAYER_SONGS \
 | 
			
		||||
        { SONG(QWERTY_SOUND), SONG(COLEMAK_SOUND), SONG(DVORAK_SOUND), SONG(OVERWATCH_THEME) }
 | 
			
		||||
 | 
			
		||||
#    define AUDIO_CLICKY_FREQ_RANDOMNESS 1.5f
 | 
			
		||||
 | 
			
		||||
#    define UNICODE_SONG_MAC SONG(RICK_ROLL)
 | 
			
		||||
#    define UNICODE_SONG_LNX SONG(RICK_ROLL)
 | 
			
		||||
#    define UNICODE_SONG_WIN SONG(RICK_ROLL)
 | 
			
		||||
#    define UNICODE_SONG_BSD SONG(RICK_ROLL)
 | 
			
		||||
#    define UNICODE_SONG_WINC SONG(RICK_ROLL)
 | 
			
		||||
#endif  // !AUDIO_ENABLE
 | 
			
		||||
#    ifdef USER_SONG_LIST
 | 
			
		||||
#        define STARTUP_SONG SONG(RICK_ROLL)
 | 
			
		||||
#        define GOODBYE_SONG SONG(SONIC_RING)
 | 
			
		||||
#        define DEFAULT_LAYER_SONGS \
 | 
			
		||||
            { SONG(QWERTY_SOUND), SONG(COLEMAK_SOUND), SONG(DVORAK_SOUND), SONG(OVERWATCH_THEME) }
 | 
			
		||||
#        define UNICODE_SONG_MAC  SONG(MARIO_THEME)
 | 
			
		||||
#        define UNICODE_SONG_LNX  SONG(MARIO_POWERUP)
 | 
			
		||||
#        define UNICODE_SONG_WIN  SONG(MARIO_ONEUP)
 | 
			
		||||
#        define UNICODE_SONG_BSD  SONG(RICK_ROLL)
 | 
			
		||||
#        define UNICODE_SONG_WINC SONG(RICK_ROLL)
 | 
			
		||||
#    else
 | 
			
		||||
#        define STARTUP_SONG SONG(STARTUP_SOUND)
 | 
			
		||||
#        define GOODBYE_SONG SONG(GOODBYE_SOUND)
 | 
			
		||||
#        define DEFAULT_LAYER_SONGS \
 | 
			
		||||
            { SONG(QWERTY_SOUND), SONG(COLEMAK_SOUND), SONG(DVORAK_SOUND), SONG(WORKMAN_SOUND) }
 | 
			
		||||
#        define UNICODE_SONG_MAC  SONG(QWERTY_SOUND)
 | 
			
		||||
#        define UNICODE_SONG_LNX  SONG(COLEMAK_SOUND)
 | 
			
		||||
#        define UNICODE_SONG_WIN  SONG(DVORAK_SOUND)
 | 
			
		||||
#        define UNICODE_SONG_BSD  SONG(WORKMAN_SOUND)
 | 
			
		||||
#        define UNICODE_SONG_WINC SONG(PLOVER_GOODBYE_SOUND)
 | 
			
		||||
#    endif
 | 
			
		||||
#endif // !AUDIO_ENABLE
 | 
			
		||||
 | 
			
		||||
#define UNICODE_SELECTED_MODES UC_WIN, UC_MAC
 | 
			
		||||
 | 
			
		||||
#ifdef RGBLIGHT_ENABLE
 | 
			
		||||
#    define RGBLIGHT_SLEEP
 | 
			
		||||
| 
						 | 
				
			
			@ -56,18 +71,16 @@
 | 
			
		|||
#    else
 | 
			
		||||
#        define RGBLIGHT_ANIMATIONS
 | 
			
		||||
#    endif
 | 
			
		||||
#    define RGBLIGHT_EFFECT_TWINKLE_LIFE  250
 | 
			
		||||
#    define RGBLIGHT_EFFECT_TWINKLE_PROBABILITY 1/24
 | 
			
		||||
#endif  // RGBLIGHT_ENABLE
 | 
			
		||||
#    define RGBLIGHT_EFFECT_TWINKLE_LIFE        250
 | 
			
		||||
#    define RGBLIGHT_EFFECT_TWINKLE_PROBABILITY 1 / 24
 | 
			
		||||
#endif // RGBLIGHT_ENABLE
 | 
			
		||||
 | 
			
		||||
#ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
#    define RGB_MATRIX_KEYPRESSES  // reacts to keypresses (will slow down matrix scan by a lot)
 | 
			
		||||
#    define RGB_MATRIX_KEYPRESSES // reacts to keypresses (will slow down matrix scan by a lot)
 | 
			
		||||
// #   define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (not recommened)
 | 
			
		||||
#    define RGB_MATRIX_FRAMEBUFFER_EFFECTS
 | 
			
		||||
// #   define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
 | 
			
		||||
#    define RGB_DISABLE_WHEN_USB_SUSPENDED  // turn off effects when suspended
 | 
			
		||||
// #   define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255
 | 
			
		||||
// #   define EECONFIG_RGB_MATRIX (uint32_t *)16
 | 
			
		||||
// #    define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
 | 
			
		||||
// #    define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended
 | 
			
		||||
 | 
			
		||||
#    if defined(__AVR__) && !defined(__AVR_AT90USB1286__) && !defined(KEYBOARD_launchpad)
 | 
			
		||||
#        define DISABLE_RGB_MATRIX_ALPHAS_MODS
 | 
			
		||||
| 
						 | 
				
			
			@ -107,8 +120,8 @@
 | 
			
		|||
#        define DISABLE_RGB_MATRIX_MULTISPLASH
 | 
			
		||||
#        define DISABLE_RGB_MATRIX_SOLID_SPLASH
 | 
			
		||||
#        define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
 | 
			
		||||
#    endif  // AVR
 | 
			
		||||
#endif      // RGB_MATRIX_ENABLE
 | 
			
		||||
#    endif // AVR
 | 
			
		||||
#endif     // RGB_MATRIX_ENABLE
 | 
			
		||||
 | 
			
		||||
#ifdef OLED_DRIVER_ENABLE
 | 
			
		||||
#    ifdef SPLIT_KEYBOARD
 | 
			
		||||
| 
						 | 
				
			
			@ -120,7 +133,7 @@
 | 
			
		|||
#    ifdef OLED_FONT_H
 | 
			
		||||
#        undef OLED_FONT_H
 | 
			
		||||
#    endif
 | 
			
		||||
#    define OLED_FONT_H "drashna_font.h"
 | 
			
		||||
#    define OLED_FONT_H   "drashna_font.h"
 | 
			
		||||
#    define OLED_FONT_END 255
 | 
			
		||||
// #    define OLED_FONT_5X5
 | 
			
		||||
// #    define OLED_FONT_AZTECH
 | 
			
		||||
| 
						 | 
				
			
			@ -135,16 +148,16 @@
 | 
			
		|||
 | 
			
		||||
#ifndef ONESHOT_TAP_TOGGLE
 | 
			
		||||
#    define ONESHOT_TAP_TOGGLE 2
 | 
			
		||||
#endif  // !ONESHOT_TAP_TOGGLE
 | 
			
		||||
#endif // !ONESHOT_TAP_TOGGLE
 | 
			
		||||
 | 
			
		||||
#ifndef ONESHOT_TIMEOUT
 | 
			
		||||
#    define ONESHOT_TIMEOUT 3000
 | 
			
		||||
#endif  // !ONESHOT_TIMEOUT
 | 
			
		||||
#endif // !ONESHOT_TIMEOUT
 | 
			
		||||
 | 
			
		||||
#ifdef QMK_KEYS_PER_SCAN
 | 
			
		||||
#    undef QMK_KEYS_PER_SCAN
 | 
			
		||||
#    define QMK_KEYS_PER_SCAN 2
 | 
			
		||||
#endif  // !QMK_KEYS_PER_SCAN
 | 
			
		||||
#endif // !QMK_KEYS_PER_SCAN
 | 
			
		||||
 | 
			
		||||
// this makes it possible to do rolling combos (zx) with keys that
 | 
			
		||||
// convert to other keys on hold (z becomes ctrl when you hold it,
 | 
			
		||||
| 
						 | 
				
			
			@ -152,8 +165,8 @@
 | 
			
		|||
// actually sends Ctrl-x. That's bad.)
 | 
			
		||||
#define IGNORE_MOD_TAP_INTERRUPT
 | 
			
		||||
#undef PERMISSIVE_HOLD
 | 
			
		||||
//#define TAPPING_FORCE_HOLD
 | 
			
		||||
//#define RETRO_TAPPING
 | 
			
		||||
//#define TAPPING_FORCE_HOLD_PER_KEY
 | 
			
		||||
//#define RETRO_TAPPING_PER_KEY
 | 
			
		||||
#ifndef KEYBOARD_kyria_rev1
 | 
			
		||||
#    define TAPPING_TERM_PER_KEY
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -166,7 +179,7 @@
 | 
			
		|||
 | 
			
		||||
#ifdef TAPPING_TERM
 | 
			
		||||
#    undef TAPPING_TERM
 | 
			
		||||
#endif  // TAPPING_TERM
 | 
			
		||||
#endif // TAPPING_TERM
 | 
			
		||||
#if defined(KEYBOARD_ergodox_ez)
 | 
			
		||||
#    define TAPPING_TERM 185
 | 
			
		||||
#elif defined(KEYBOARD_crkbd)
 | 
			
		||||
| 
						 | 
				
			
			@ -185,14 +198,16 @@
 | 
			
		|||
#    undef LOCKING_RESYNC_ENABLE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define LAYER_STATE_16BIT
 | 
			
		||||
 | 
			
		||||
#ifdef CONVERT_TO_PROTON_C
 | 
			
		||||
// pins that are available but not present on Pro Micro
 | 
			
		||||
#    define A3 PAL_LINE(GPIOA, 3)
 | 
			
		||||
#    define A4 PAL_LINE(GPIOA, 4)
 | 
			
		||||
#    define A5 PAL_LINE(GPIOA, 5)
 | 
			
		||||
#    define A6 PAL_LINE(GPIOA, 6)
 | 
			
		||||
#    define A7 PAL_LINE(GPIOA, 7)
 | 
			
		||||
#    define A8 PAL_LINE(GPIOA, 8)
 | 
			
		||||
#    define A3  PAL_LINE(GPIOA, 3)
 | 
			
		||||
#    define A4  PAL_LINE(GPIOA, 4)
 | 
			
		||||
#    define A5  PAL_LINE(GPIOA, 5)
 | 
			
		||||
#    define A6  PAL_LINE(GPIOA, 6)
 | 
			
		||||
#    define A7  PAL_LINE(GPIOA, 7)
 | 
			
		||||
#    define A8  PAL_LINE(GPIOA, 8)
 | 
			
		||||
#    define A13 PAL_LINE(GPIOA, 13)
 | 
			
		||||
#    define A14 PAL_LINE(GPIOA, 14)
 | 
			
		||||
#    define A15 PAL_LINE(GPIOA, 15)
 | 
			
		||||
| 
						 | 
				
			
			@ -203,3 +218,79 @@
 | 
			
		|||
#    define C14 PAL_LINE(GPIOC, 14)
 | 
			
		||||
#    define C15 PAL_LINE(GPIOC, 15)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MOUSEKEY_ENABLE
 | 
			
		||||
// mouse movement config
 | 
			
		||||
#    ifdef MK_3_SPEED
 | 
			
		||||
#        undef MK_3_SPEED
 | 
			
		||||
#    endif
 | 
			
		||||
#    define MK_KINETIC_SPEED
 | 
			
		||||
#    ifdef MK_KINETIC_SPEED
 | 
			
		||||
#        ifndef MOUSEKEY_DELAY
 | 
			
		||||
#            define MOUSEKEY_DELAY 8
 | 
			
		||||
#        endif
 | 
			
		||||
#        ifndef MOUSEKEY_INTERVAL
 | 
			
		||||
#            define MOUSEKEY_INTERVAL 20
 | 
			
		||||
#        endif
 | 
			
		||||
#        ifdef MOUSEKEY_MOVE_DELTA
 | 
			
		||||
#            define MOUSEKEY_MOVE_DELTA 25
 | 
			
		||||
#        endif
 | 
			
		||||
#    else
 | 
			
		||||
#        ifndef MOUSEKEY_DELAY
 | 
			
		||||
#            define MOUSEKEY_DELAY 300
 | 
			
		||||
#        endif
 | 
			
		||||
#        ifndef MOUSEKEY_INTERVAL
 | 
			
		||||
#            define MOUSEKEY_INTERVAL 50
 | 
			
		||||
#        endif
 | 
			
		||||
#        ifndef MOUSEKEY_MOVE_DELTA
 | 
			
		||||
#            define MOUSEKEY_MOVE_DELTA 5
 | 
			
		||||
#        endif
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef MOUSEKEY_MAX_SPEED
 | 
			
		||||
#        define MOUSEKEY_MAX_SPEED 7
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef MOUSEKEY_TIME_TO_MAX
 | 
			
		||||
#        define MOUSEKEY_TIME_TO_MAX 60
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef MOUSEKEY_INITIAL_SPEED
 | 
			
		||||
#        define MOUSEKEY_INITIAL_SPEED 100
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef MOUSEKEY_BASE_SPEED
 | 
			
		||||
#        define MOUSEKEY_BASE_SPEED 1000
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef MOUSEKEY_DECELERATED_SPEED
 | 
			
		||||
#        define MOUSEKEY_DECELERATED_SPEED 400
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef MOUSEKEY_ACCELERATED_SPEED
 | 
			
		||||
#        define MOUSEKEY_ACCELERATED_SPEED 3000
 | 
			
		||||
#    endif
 | 
			
		||||
// mouse scroll config
 | 
			
		||||
#    ifndef MOUSEKEY_WHEEL_DELAY
 | 
			
		||||
#        define MOUSEKEY_WHEEL_DELAY 15
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef MOUSEKEY_WHEEL_DELTA
 | 
			
		||||
#        define MOUSEKEY_WHEEL_DELTA 1
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef MOUSEKEY_WHEEL_INTERVAL
 | 
			
		||||
#        define MOUSEKEY_WHEEL_INTERVAL 50
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef MOUSEKEY_WHEEL_MAX_SPEED
 | 
			
		||||
#        define MOUSEKEY_WHEEL_MAX_SPEED 8
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef MOUSEKEY_WHEEL_TIME_TO_MAX
 | 
			
		||||
#        define MOUSEKEY_WHEEL_TIME_TO_MAX 80
 | 
			
		||||
#    endif
 | 
			
		||||
// mouse scroll kinetic config
 | 
			
		||||
#    ifndef MOUSEKEY_WHEEL_INITIAL_MOVEMENTS
 | 
			
		||||
#        define MOUSEKEY_WHEEL_INITIAL_MOVEMENTS 8
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef MOUSEKEY_WHEEL_BASE_MOVEMENTS
 | 
			
		||||
#        define MOUSEKEY_WHEEL_BASE_MOVEMENTS 48
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS
 | 
			
		||||
#        define MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS 48
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS
 | 
			
		||||
#        define MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS 8
 | 
			
		||||
#    endif
 | 
			
		||||
#endif // MOUSEKEY_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,6 +85,9 @@ void keyboard_post_init_user(void) {
 | 
			
		|||
#endif
 | 
			
		||||
#if defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
    keyboard_post_init_rgb_matrix();
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(SPLIT_KEYBOARD) && defined(SPLIT_TRANSACTION_IDS_USER)
 | 
			
		||||
    keyboard_post_init_transport_sync();
 | 
			
		||||
#endif
 | 
			
		||||
    keyboard_post_init_keymap();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -100,12 +103,12 @@ void shutdown_user(void) {
 | 
			
		|||
    rgblight_enable_noeeprom();
 | 
			
		||||
    rgblight_mode_noeeprom(1);
 | 
			
		||||
    rgblight_setrgb_red();
 | 
			
		||||
#endif  // RGBLIGHT_ENABLE
 | 
			
		||||
#endif // RGBLIGHT_ENABLE
 | 
			
		||||
#ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
    rgb_matrix_set_color_all(0xFF, 0x00, 0x00);
 | 
			
		||||
    rgb_matrix_update_pwm_buffers();
 | 
			
		||||
 | 
			
		||||
#endif  // RGB_MATRIX_ENABLE
 | 
			
		||||
#endif // RGB_MATRIX_ENABLE
 | 
			
		||||
    shutdown_keymap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -120,7 +123,11 @@ void suspend_power_down_user(void) {
 | 
			
		|||
 | 
			
		||||
__attribute__((weak)) void suspend_wakeup_init_keymap(void) {}
 | 
			
		||||
 | 
			
		||||
void suspend_wakeup_init_user(void) { suspend_wakeup_init_keymap(); }
 | 
			
		||||
void suspend_wakeup_init_user(void) {
 | 
			
		||||
    if (layer_state_is(_GAMEPAD)) { layer_off(_GAMEPAD); }
 | 
			
		||||
    if (layer_state_is(_DIABLO)) { layer_off(_DIABLO); }
 | 
			
		||||
    suspend_wakeup_init_keymap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) void matrix_scan_keymap(void) {}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -135,13 +142,13 @@ void matrix_scan_user(void) {
 | 
			
		|||
        startup_user();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef TAP_DANCE_ENABLE  // Run Diablo 3 macro checking code.
 | 
			
		||||
#ifdef TAP_DANCE_ENABLE // Run Diablo 3 macro checking code.
 | 
			
		||||
    run_diablo_macro_check();
 | 
			
		||||
#endif  // TAP_DANCE_ENABLE
 | 
			
		||||
#endif // TAP_DANCE_ENABLE
 | 
			
		||||
 | 
			
		||||
#if defined(RGBLIGHT_ENABLE)
 | 
			
		||||
    matrix_scan_rgb_light();
 | 
			
		||||
#endif  // RGBLIGHT_ENABLE
 | 
			
		||||
#endif // RGBLIGHT_ENABLE
 | 
			
		||||
#if defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
    matrix_scan_rgb_matrix();
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -160,15 +167,13 @@ __attribute__((weak)) layer_state_t layer_state_set_keymap(layer_state_t state)
 | 
			
		|||
// on layer change, no matter where the change was initiated
 | 
			
		||||
// Then runs keymap's layer change check
 | 
			
		||||
layer_state_t layer_state_set_user(layer_state_t state) {
 | 
			
		||||
    if (!is_keyboard_master()) {
 | 
			
		||||
        return state;
 | 
			
		||||
    }
 | 
			
		||||
    if (!is_keyboard_master()) { return state; }
 | 
			
		||||
 | 
			
		||||
    state = layer_state_set_keymap(state);
 | 
			
		||||
    state = update_tri_layer_state(state, _RAISE, _LOWER, _ADJUST);
 | 
			
		||||
#if defined(RGBLIGHT_ENABLE)
 | 
			
		||||
    state = layer_state_set_rgb_light(state);
 | 
			
		||||
#endif  // RGBLIGHT_ENABLE
 | 
			
		||||
#endif // RGBLIGHT_ENABLE
 | 
			
		||||
#if defined(AUDIO_ENABLE) && !defined(__arm__)
 | 
			
		||||
    static bool is_gamepad_on = false;
 | 
			
		||||
    if (layer_state_cmp(state, _GAMEPAD) != is_gamepad_on) {
 | 
			
		||||
| 
						 | 
				
			
			@ -187,15 +192,13 @@ __attribute__((weak)) layer_state_t default_layer_state_set_keymap(layer_state_t
 | 
			
		|||
 | 
			
		||||
// Runs state check and changes underglow color and animation
 | 
			
		||||
layer_state_t default_layer_state_set_user(layer_state_t state) {
 | 
			
		||||
    if (!is_keyboard_master()) {
 | 
			
		||||
        return state;
 | 
			
		||||
    }
 | 
			
		||||
    if (!is_keyboard_master()) { return state; }
 | 
			
		||||
 | 
			
		||||
    state = default_layer_state_set_keymap(state);
 | 
			
		||||
#if 0
 | 
			
		||||
#    if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
  state = default_layer_state_set_rgb(state);
 | 
			
		||||
#    endif  // RGBLIGHT_ENABLE
 | 
			
		||||
#    endif // RGBLIGHT_ENABLE
 | 
			
		||||
#endif
 | 
			
		||||
    return state;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@
 | 
			
		|||
#include "process_records.h"
 | 
			
		||||
#ifdef TAP_DANCE_ENABLE
 | 
			
		||||
#    include "tap_dances.h"
 | 
			
		||||
#endif  // TAP_DANCE_ENABLE
 | 
			
		||||
#endif // TAP_DANCE_ENABLE
 | 
			
		||||
#if defined(RGBLIGHT_ENABLE)
 | 
			
		||||
#    include "rgb_stuff.h"
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +35,9 @@
 | 
			
		|||
#if defined(PIMORONI_TRACKBALL_ENABLE)
 | 
			
		||||
#    include "drivers/sensors/pimoroni_trackball.h"
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SPLIT_KEYBOARD
 | 
			
		||||
#    include "transport_sync.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Define layer names */
 | 
			
		||||
enum userspace_layers {
 | 
			
		||||
| 
						 | 
				
			
			@ -98,12 +101,12 @@ We use custom codes here, so we can substitute the right stuff
 | 
			
		|||
#    define KC_D3_2 TD(TD_D3_2)
 | 
			
		||||
#    define KC_D3_3 TD(TD_D3_3)
 | 
			
		||||
#    define KC_D3_4 TD(TD_D3_4)
 | 
			
		||||
#else  // TAP_DANCE_ENABLE
 | 
			
		||||
#else // TAP_DANCE_ENABLE
 | 
			
		||||
#    define KC_D3_1 KC_1
 | 
			
		||||
#    define KC_D3_2 KC_2
 | 
			
		||||
#    define KC_D3_3 KC_3
 | 
			
		||||
#    define KC_D3_4 KC_4
 | 
			
		||||
#endif  // TAP_DANCE_ENABLE
 | 
			
		||||
#endif // TAP_DANCE_ENABLE
 | 
			
		||||
 | 
			
		||||
#if defined(DRASHNA_CUSTOM_TRANSPORT) && defined(POINTING_DEVICE_ENABLE)
 | 
			
		||||
void master_mouse_send(int8_t x, int8_t y);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,8 +5,9 @@
 | 
			
		|||
 | 
			
		||||
#include "progmem.h"
 | 
			
		||||
 | 
			
		||||
// clang-format off
 | 
			
		||||
static const unsigned char font[] PROGMEM = {
 | 
			
		||||
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 0
 | 
			
		||||
    0x07, 0x08, 0x7F, 0x08, 0x07, 0x00, // 0x00 0
 | 
			
		||||
    0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00, // 0x01 1
 | 
			
		||||
    0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00, // 0x02 2
 | 
			
		||||
    0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00, // 0x03 3 ♥
 | 
			
		||||
| 
						 | 
				
			
			@ -1304,3 +1305,5 @@ static const unsigned char font[] PROGMEM = {
 | 
			
		|||
 | 
			
		||||
#endif
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
// clang-format on
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,603 +0,0 @@
 | 
			
		|||
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're  (@drashna) <drashna@live.com>
 | 
			
		||||
 *
 | 
			
		||||
 * 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 <string.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
#include "matrix.h"
 | 
			
		||||
#include QMK_KEYBOARD_H
 | 
			
		||||
 | 
			
		||||
#define ROWS_PER_HAND (MATRIX_ROWS / 2)
 | 
			
		||||
#define SYNC_TIMER_OFFSET 2
 | 
			
		||||
 | 
			
		||||
#ifdef RGBLIGHT_ENABLE
 | 
			
		||||
#    include "rgblight.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BACKLIGHT_ENABLE
 | 
			
		||||
#    include "backlight.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ENCODER_ENABLE
 | 
			
		||||
#    include "encoder.h"
 | 
			
		||||
static pin_t encoders_pad[] = ENCODERS_PAD_A;
 | 
			
		||||
#    define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef POINTING_DEVICE_ENABLE
 | 
			
		||||
static uint16_t device_cpi    = 0;
 | 
			
		||||
static int8_t   split_mouse_x = 0, split_mouse_y = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef OLED_DRIVER_ENABLE
 | 
			
		||||
#    include "oled_driver.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
 | 
			
		||||
#    include "led_matrix.h"
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
 | 
			
		||||
#    include "rgb_matrix.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(USE_I2C)
 | 
			
		||||
 | 
			
		||||
#    include "i2c_master.h"
 | 
			
		||||
#    include "i2c_slave.h"
 | 
			
		||||
 | 
			
		||||
typedef struct _I2C_slave_buffer_t {
 | 
			
		||||
#    ifndef DISABLE_SYNC_TIMER
 | 
			
		||||
    uint32_t sync_timer;
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifdef SPLIT_TRANSPORT_MIRROR
 | 
			
		||||
    matrix_row_t mmatrix[ROWS_PER_HAND];
 | 
			
		||||
#    endif
 | 
			
		||||
    matrix_row_t smatrix[ROWS_PER_HAND];
 | 
			
		||||
#    ifdef SPLIT_MODS_ENABLE
 | 
			
		||||
    uint8_t real_mods;
 | 
			
		||||
    uint8_t weak_mods;
 | 
			
		||||
#        ifndef NO_ACTION_ONESHOT
 | 
			
		||||
    uint8_t oneshot_mods;
 | 
			
		||||
#        endif
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifdef BACKLIGHT_ENABLE
 | 
			
		||||
    uint8_t backlight_level;
 | 
			
		||||
#    endif
 | 
			
		||||
#    if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
 | 
			
		||||
    rgblight_syncinfo_t rgblight_sync;
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifdef ENCODER_ENABLE
 | 
			
		||||
    uint8_t encoder_state[NUMBER_OF_ENCODERS];
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifdef WPM_ENABLE
 | 
			
		||||
    uint8_t current_wpm;
 | 
			
		||||
#    endif
 | 
			
		||||
#    if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
 | 
			
		||||
    led_eeconfig_t led_matrix;
 | 
			
		||||
    bool           led_suspend_state;
 | 
			
		||||
#    endif
 | 
			
		||||
#    if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
 | 
			
		||||
    rgb_config_t rgb_matrix;
 | 
			
		||||
    bool         rgb_suspend_state;
 | 
			
		||||
#    endif
 | 
			
		||||
    int8_t        mouse_x;
 | 
			
		||||
    int8_t        mouse_y;
 | 
			
		||||
    uint16_t      device_cpi;
 | 
			
		||||
    bool          oled_on;
 | 
			
		||||
    layer_state_t t_layer_state;
 | 
			
		||||
    layer_state_t t_default_layer_state;
 | 
			
		||||
} __attribute__((packed)) I2C_slave_buffer_t;
 | 
			
		||||
 | 
			
		||||
static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;
 | 
			
		||||
 | 
			
		||||
#    define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level)
 | 
			
		||||
#    define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
 | 
			
		||||
#    define I2C_KEYMAP_MASTER_START offsetof(I2C_slave_buffer_t, mmatrix)
 | 
			
		||||
#    define I2C_KEYMAP_SLAVE_START offsetof(I2C_slave_buffer_t, smatrix)
 | 
			
		||||
#    define I2C_SYNC_TIME_START offsetof(I2C_slave_buffer_t, sync_timer)
 | 
			
		||||
#    define I2C_REAL_MODS_START offsetof(I2C_slave_buffer_t, real_mods)
 | 
			
		||||
#    define I2C_WEAK_MODS_START offsetof(I2C_slave_buffer_t, weak_mods)
 | 
			
		||||
#    define I2C_ONESHOT_MODS_START offsetof(I2C_slave_buffer_t, oneshot_mods)
 | 
			
		||||
#    define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state)
 | 
			
		||||
#    define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm)
 | 
			
		||||
#    define I2C_MOUSE_X_START offsetof(I2C_slave_buffer_t, mouse_x)
 | 
			
		||||
#    define I2C_MOUSE_Y_START offsetof(I2C_slave_buffer_t, mouse_y)
 | 
			
		||||
#    define I2C_MOUSE_DPI_START offsetof(I2C_slave_buffer_t, device_cpi)
 | 
			
		||||
#    define I2C_OLED_ON_START offsetof(I2C_slave_buffer_t, oled_on)
 | 
			
		||||
#    define I2C_LAYER_STATE_START offsetof(I2C_slave_buffer_t, t_layer_state)
 | 
			
		||||
#    define I2C_DEFAULT_LAYER_STATE_START offsetof(I2C_slave_buffer_t, t_default_layer_state)
 | 
			
		||||
#    define I2C_LED_MATRIX_START offsetof(I2C_slave_buffer_t, led_matrix)
 | 
			
		||||
#    define I2C_LED_SUSPEND_START offsetof(I2C_slave_buffer_t, led_suspend_state)
 | 
			
		||||
#    define I2C_RGB_MATRIX_START offsetof(I2C_slave_buffer_t, rgb_matrix)
 | 
			
		||||
#    define I2C_RGB_SUSPEND_START offsetof(I2C_slave_buffer_t, rgb_suspend_state)
 | 
			
		||||
 | 
			
		||||
#    define TIMEOUT 100
 | 
			
		||||
 | 
			
		||||
#    ifndef SLAVE_I2C_ADDRESS
 | 
			
		||||
#        define SLAVE_I2C_ADDRESS 0x32
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
// Get rows from other half over i2c
 | 
			
		||||
bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
 | 
			
		||||
    i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_SLAVE_START, (void *)slave_matrix, sizeof(i2c_buffer->smatrix), TIMEOUT);
 | 
			
		||||
#    ifdef SPLIT_TRANSPORT_MIRROR
 | 
			
		||||
    i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_MASTER_START, (void *)master_matrix, sizeof(i2c_buffer->mmatrix), TIMEOUT);
 | 
			
		||||
#    endif
 | 
			
		||||
    // write backlight info
 | 
			
		||||
#    ifdef BACKLIGHT_ENABLE
 | 
			
		||||
    uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0;
 | 
			
		||||
    if (level != i2c_buffer->backlight_level) {
 | 
			
		||||
        if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIGHT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) {
 | 
			
		||||
            i2c_buffer->backlight_level = level;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
 | 
			
		||||
    if (rgblight_get_change_flags()) {
 | 
			
		||||
        rgblight_syncinfo_t rgblight_sync;
 | 
			
		||||
        rgblight_get_syncinfo(&rgblight_sync);
 | 
			
		||||
        if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) {
 | 
			
		||||
            rgblight_clear_change_flags();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef ENCODER_ENABLE
 | 
			
		||||
    i2c_readReg(SLAVE_I2C_ADDRESS, I2C_ENCODER_START, (void *)i2c_buffer->encoder_state, sizeof(i2c_buffer->encoder_state), TIMEOUT);
 | 
			
		||||
    encoder_update_raw(i2c_buffer->encoder_state);
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef WPM_ENABLE
 | 
			
		||||
    uint8_t current_wpm = get_current_wpm();
 | 
			
		||||
    if (current_wpm != i2c_buffer->current_wpm) {
 | 
			
		||||
        if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WPM_START, (void *)¤t_wpm, sizeof(current_wpm), TIMEOUT) >= 0) {
 | 
			
		||||
            i2c_buffer->current_wpm = current_wpm;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef POINTING_DEVICE_ENABLE
 | 
			
		||||
    if (is_keyboard_left()) {
 | 
			
		||||
        report_mouse_t temp_report = pointing_device_get_report();
 | 
			
		||||
        i2c_readReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_X_START, (void *)&i2c_buffer->mouse_x, sizeof(i2c_buffer->mouse_x), TIMEOUT);
 | 
			
		||||
        temp_report.x = i2c_buffer->mouse_x;
 | 
			
		||||
        i2c_readReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_Y_START, (void *)&i2c_buffer->mouse_y, sizeof(i2c_buffer->mouse_y), TIMEOUT);
 | 
			
		||||
        temp_report.y = i2c_buffer->mouse_y;
 | 
			
		||||
        pointing_device_set_report(temp_report);
 | 
			
		||||
 | 
			
		||||
        if (device_cpi != i2c_buffer->device_cpi) {
 | 
			
		||||
            if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_DPI_START, (void *)&device_cpi, sizeof(device_cpi), TIMEOUT) >= 0) {
 | 
			
		||||
                i2c_buffer->device_cpi = device_cpi
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef SPLIT_MODS_ENABLE
 | 
			
		||||
    uint8_t real_mods = get_mods();
 | 
			
		||||
    if (real_mods != i2c_buffer->real_mods) {
 | 
			
		||||
        if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_REAL_MODS_START, (void *)&real_mods, sizeof(real_mods), TIMEOUT) >= 0) {
 | 
			
		||||
            i2c_buffer->real_mods = real_mods;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint8_t weak_mods = get_weak_mods();
 | 
			
		||||
    if (weak_mods != i2c_buffer->weak_mods) {
 | 
			
		||||
        if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WEAK_MODS_START, (void *)&weak_mods, sizeof(weak_mods), TIMEOUT) >= 0) {
 | 
			
		||||
            i2c_buffer->weak_mods = weak_mods;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#        ifndef NO_ACTION_ONESHOT
 | 
			
		||||
    uint8_t oneshot_mods = get_oneshot_mods();
 | 
			
		||||
    if (oneshot_mods != i2c_buffer->oneshot_mods) {
 | 
			
		||||
        if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_ONESHOT_MODS_START, (void *)&oneshot_mods, sizeof(oneshot_mods), TIMEOUT) >= 0) {
 | 
			
		||||
            i2c_buffer->oneshot_mods = oneshot_mods;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#        endif
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    if (layer_state != i2c_buffer->t_layer_state) {
 | 
			
		||||
        if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LAYER_STATE_START, (void *)&layer_state, sizeof(layer_state), TIMEOUT) >= 0) {
 | 
			
		||||
            i2c_buffer->t_layer_state = layer_state;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (default_layer_state != i2c_buffer->t_default_layer_state) {
 | 
			
		||||
        if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_DEFAULT_LAYER_STATE_START, (void *)&default_layer_state, sizeof(default_layer_state), TIMEOUT) >= 0) {
 | 
			
		||||
            i2c_buffer->t_default_layer_state = default_layer_state;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#    ifdef OLED_DRIVER_ENABLE
 | 
			
		||||
    bool is_oled_on = is_oled_on();
 | 
			
		||||
    if (is_oled_on != i2c_buffer->oled_on) {
 | 
			
		||||
        if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LAYER_STATE_START, (void *)&is_oled_on, sizeof(is_oled_on), TIMEOUT) >= 0) {
 | 
			
		||||
            i2c_buffer->oled_on = is_oled_on;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
 | 
			
		||||
    i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_MATRIX_START, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix), TIMEOUT);
 | 
			
		||||
    bool suspend_state = led_matrix_get_suspend_state();
 | 
			
		||||
    i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->led_suspend_state), TIMEOUT);
 | 
			
		||||
#    endif
 | 
			
		||||
#    if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
 | 
			
		||||
    i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_MATRIX_START, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix), TIMEOUT);
 | 
			
		||||
    bool suspend_state = rgb_matrix_get_suspend_state();
 | 
			
		||||
    i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->rgb_suspend_state), TIMEOUT);
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifndef DISABLE_SYNC_TIMER
 | 
			
		||||
    i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
 | 
			
		||||
    i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT);
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
 | 
			
		||||
#    ifndef DISABLE_SYNC_TIMER
 | 
			
		||||
    sync_timer_update(i2c_buffer->sync_timer);
 | 
			
		||||
#    endif
 | 
			
		||||
    // Copy matrix to I2C buffer
 | 
			
		||||
    memcpy((void *)i2c_buffer->smatrix, (void *)slave_matrix, sizeof(i2c_buffer->smatrix));
 | 
			
		||||
#    ifdef SPLIT_TRANSPORT_MIRROR
 | 
			
		||||
    memcpy((void *)master_matrix, (void *)i2c_buffer->mmatrix, sizeof(i2c_buffer->mmatrix));
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
// Read Backlight Info
 | 
			
		||||
#    ifdef BACKLIGHT_ENABLE
 | 
			
		||||
    backlight_set(i2c_buffer->backlight_level);
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
 | 
			
		||||
    // Update the RGB with the new data
 | 
			
		||||
    if (i2c_buffer->rgblight_sync.status.change_flags != 0) {
 | 
			
		||||
        rgblight_update_sync(&i2c_buffer->rgblight_sync, false);
 | 
			
		||||
        i2c_buffer->rgblight_sync.status.change_flags = 0;
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef ENCODER_ENABLE
 | 
			
		||||
    encoder_state_raw(i2c_buffer->encoder_state);
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef WPM_ENABLE
 | 
			
		||||
    set_current_wpm(i2c_buffer->current_wpm);
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef POINTING_DEVICE_ENABLE
 | 
			
		||||
    if (!is_keyboard_left()) {
 | 
			
		||||
        static uint16_t cpi;
 | 
			
		||||
        if (cpi != i2c_buffer->device_cpi) {
 | 
			
		||||
            cpi = i2c_buffer->device_cpi;
 | 
			
		||||
            pmw_set_cpi(cpi);
 | 
			
		||||
        }
 | 
			
		||||
        i2c_buffer->mouse_x = split_mouse_x;
 | 
			
		||||
        i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_X_START, (void *)&i2c_buffer->mouse_x, sizeof(i2c_buffer->mouse_x), TIMEOUT);
 | 
			
		||||
        i2c_buffer->mouse_y = split_mouse_y;
 | 
			
		||||
        i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_MOUSE_Y_START, (void *)&i2c_buffer->mouse_y, sizeof(i2c_buffer->mouse_y), TIMEOUT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef SPLIT_MODS_ENABLE
 | 
			
		||||
    set_mods(i2c_buffer->real_mods);
 | 
			
		||||
    set_weak_mods(i2c_buffer->weak_mods);
 | 
			
		||||
#        ifndef NO_ACTION_ONESHOT
 | 
			
		||||
    set_oneshot_mods(i2c_buffer->oneshot_mods);
 | 
			
		||||
#        endif
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    if (layer_state != i2c_buffer->t_layer_state) {
 | 
			
		||||
        layer_state = i2c_buffer->t_layer_state;
 | 
			
		||||
    }
 | 
			
		||||
    if (default_layer_state != i2c_buffer->t_default_layer_state) {
 | 
			
		||||
        default_layer_state = i2c_buffer->t_default_layer_state;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#    ifdef OLED_DRIVER_ENABLE
 | 
			
		||||
    if (i2c_buffer->oled_on) {
 | 
			
		||||
        oled_on();
 | 
			
		||||
    } else {
 | 
			
		||||
        oled_off();
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
 | 
			
		||||
    memcpy((void *)i2c_buffer->led_matrix, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix));
 | 
			
		||||
    led_matrix_set_suspend_state(i2c_buffer->led_suspend_state);
 | 
			
		||||
#    endif
 | 
			
		||||
#    if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
 | 
			
		||||
    memcpy((void *)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix));
 | 
			
		||||
    rgb_matrix_set_suspend_state(i2c_buffer->rgb_suspend_state);
 | 
			
		||||
#    endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void transport_master_init(void) { i2c_init(); }
 | 
			
		||||
 | 
			
		||||
void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); }
 | 
			
		||||
 | 
			
		||||
#else  // USE_SERIAL
 | 
			
		||||
 | 
			
		||||
#    include "serial.h"
 | 
			
		||||
 | 
			
		||||
typedef struct _Serial_s2m_buffer_t {
 | 
			
		||||
    // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack
 | 
			
		||||
    matrix_row_t smatrix[ROWS_PER_HAND];
 | 
			
		||||
#    ifdef ENCODER_ENABLE
 | 
			
		||||
    uint8_t      encoder_state[NUMBER_OF_ENCODERS];
 | 
			
		||||
#    endif
 | 
			
		||||
    int8_t       mouse_x;
 | 
			
		||||
    int8_t       mouse_y;
 | 
			
		||||
} __attribute__((packed)) Serial_s2m_buffer_t;
 | 
			
		||||
 | 
			
		||||
typedef struct _Serial_m2s_buffer_t {
 | 
			
		||||
#    ifdef SPLIT_MODS_ENABLE
 | 
			
		||||
    uint8_t       real_mods;
 | 
			
		||||
    uint8_t       weak_mods;
 | 
			
		||||
#        ifndef NO_ACTION_ONESHOT
 | 
			
		||||
    uint8_t       oneshot_mods;
 | 
			
		||||
#        endif
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifndef DISABLE_SYNC_TIMER
 | 
			
		||||
    uint32_t     sync_timer;
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifdef SPLIT_TRANSPORT_MIRROR
 | 
			
		||||
    matrix_row_t mmatrix[ROWS_PER_HAND];
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifdef BACKLIGHT_ENABLE
 | 
			
		||||
    uint8_t       backlight_level;
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifdef WPM_ENABLE
 | 
			
		||||
    uint8_t       current_wpm;
 | 
			
		||||
#    endif
 | 
			
		||||
    uint16_t      device_cpi;
 | 
			
		||||
    bool          oled_on;
 | 
			
		||||
    layer_state_t t_layer_state;
 | 
			
		||||
    layer_state_t t_default_layer_state;
 | 
			
		||||
#    if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
 | 
			
		||||
    led_eeconfig_t led_matrix;
 | 
			
		||||
    bool           led_suspend_state;
 | 
			
		||||
#    endif
 | 
			
		||||
#    if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
 | 
			
		||||
    rgb_config_t   rgb_matrix;
 | 
			
		||||
    bool           rgb_suspend_state;
 | 
			
		||||
#    endif
 | 
			
		||||
} __attribute__((packed)) Serial_m2s_buffer_t;
 | 
			
		||||
 | 
			
		||||
#    if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
 | 
			
		||||
// When MCUs on both sides drive their respective RGB LED chains,
 | 
			
		||||
// it is necessary to synchronize, so it is necessary to communicate RGB
 | 
			
		||||
// information. In that case, define RGBLIGHT_SPLIT with info on the number
 | 
			
		||||
// of LEDs on each half.
 | 
			
		||||
//
 | 
			
		||||
// Otherwise, if the master side MCU drives both sides RGB LED chains,
 | 
			
		||||
// there is no need to communicate.
 | 
			
		||||
 | 
			
		||||
typedef struct _Serial_rgblight_t {
 | 
			
		||||
    rgblight_syncinfo_t rgblight_sync;
 | 
			
		||||
} Serial_rgblight_t;
 | 
			
		||||
 | 
			
		||||
volatile Serial_rgblight_t serial_rgblight = {};
 | 
			
		||||
uint8_t volatile status_rgblight           = 0;
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
volatile Serial_s2m_buffer_t serial_s2m_buffer = {};
 | 
			
		||||
volatile Serial_m2s_buffer_t serial_m2s_buffer = {};
 | 
			
		||||
uint8_t volatile status0                       = 0;
 | 
			
		||||
 | 
			
		||||
enum serial_transaction_id {
 | 
			
		||||
    GET_SLAVE_MATRIX = 0,
 | 
			
		||||
#    if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
 | 
			
		||||
    PUT_RGBLIGHT,
 | 
			
		||||
#    endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
SSTD_t transactions[] = {
 | 
			
		||||
    [GET_SLAVE_MATRIX] =
 | 
			
		||||
        {
 | 
			
		||||
            (uint8_t *)&status0,
 | 
			
		||||
            sizeof(serial_m2s_buffer),
 | 
			
		||||
            (uint8_t *)&serial_m2s_buffer,
 | 
			
		||||
            sizeof(serial_s2m_buffer),
 | 
			
		||||
            (uint8_t *)&serial_s2m_buffer,
 | 
			
		||||
        },
 | 
			
		||||
#    if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
 | 
			
		||||
    [PUT_RGBLIGHT] =
 | 
			
		||||
        {
 | 
			
		||||
            (uint8_t *)&status_rgblight, sizeof(serial_rgblight), (uint8_t *)&serial_rgblight, 0, NULL  // no slave to master transfer
 | 
			
		||||
        },
 | 
			
		||||
#    endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); }
 | 
			
		||||
 | 
			
		||||
void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); }
 | 
			
		||||
 | 
			
		||||
#    if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
 | 
			
		||||
 | 
			
		||||
// rgblight synchronization information communication.
 | 
			
		||||
 | 
			
		||||
void transport_rgblight_master(void) {
 | 
			
		||||
    if (rgblight_get_change_flags()) {
 | 
			
		||||
        rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync);
 | 
			
		||||
        if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) {
 | 
			
		||||
            rgblight_clear_change_flags();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void transport_rgblight_slave(void) {
 | 
			
		||||
    if (status_rgblight == TRANSACTION_ACCEPTED) {
 | 
			
		||||
        rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync, false);
 | 
			
		||||
        status_rgblight = TRANSACTION_END;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#    else
 | 
			
		||||
#        define transport_rgblight_master()
 | 
			
		||||
#        define transport_rgblight_slave()
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
 | 
			
		||||
#    ifndef SERIAL_USE_MULTI_TRANSACTION
 | 
			
		||||
    if (soft_serial_transaction() != TRANSACTION_END) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
#    else
 | 
			
		||||
    transport_rgblight_master();
 | 
			
		||||
    if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    // TODO:  if MATRIX_COLS > 8 change to unpack()
 | 
			
		||||
    for (int i = 0; i < ROWS_PER_HAND; ++i) {
 | 
			
		||||
        slave_matrix[i] = serial_s2m_buffer.smatrix[i];
 | 
			
		||||
#    ifdef SPLIT_TRANSPORT_MIRROR
 | 
			
		||||
        serial_m2s_buffer.mmatrix[i] = master_matrix[i];
 | 
			
		||||
#    endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#    ifdef BACKLIGHT_ENABLE
 | 
			
		||||
    // Write backlight level for slave to read
 | 
			
		||||
    serial_m2s_buffer.backlight_level = is_backlight_enabled() ? get_backlight_level() : 0;
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef ENCODER_ENABLE
 | 
			
		||||
    encoder_update_raw((uint8_t *)serial_s2m_buffer.encoder_state);
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef WPM_ENABLE
 | 
			
		||||
    // Write wpm to slave
 | 
			
		||||
    serial_m2s_buffer.current_wpm  = get_current_wpm();
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef SPLIT_MODS_ENABLE
 | 
			
		||||
    serial_m2s_buffer.real_mods    = get_mods();
 | 
			
		||||
    serial_m2s_buffer.weak_mods    = get_weak_mods();
 | 
			
		||||
#        ifndef NO_ACTION_ONESHOT
 | 
			
		||||
    serial_m2s_buffer.oneshot_mods = get_oneshot_mods();
 | 
			
		||||
#        endif
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef POINTING_DEVICE_ENABLE
 | 
			
		||||
    if (is_keyboard_left()) {
 | 
			
		||||
        report_mouse_t temp_report = pointing_device_get_report();
 | 
			
		||||
        temp_report.x              = serial_s2m_buffer.mouse_x;
 | 
			
		||||
        temp_report.y              = serial_s2m_buffer.mouse_y;
 | 
			
		||||
        pointing_device_set_report(temp_report);
 | 
			
		||||
        serial_m2s_buffer.device_cpi = device_cpi;
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    serial_m2s_buffer.t_layer_state           = layer_state;
 | 
			
		||||
    serial_m2s_buffer.t_default_layer_state   = default_layer_state;
 | 
			
		||||
#    ifdef OLED_DRIVER_ENABLE
 | 
			
		||||
    serial_m2s_buffer.oled_on                 = is_oled_on();
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
 | 
			
		||||
    serial_m2s_buffer.led_matrix        = led_matrix_eeconfig;
 | 
			
		||||
    serial_m2s_buffer.led_suspend_state = led_matrix_get_suspend_state();
 | 
			
		||||
#    endif
 | 
			
		||||
#    if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
 | 
			
		||||
    serial_m2s_buffer.rgb_matrix        = rgb_matrix_config;
 | 
			
		||||
    serial_m2s_buffer.rgb_suspend_state = rgb_matrix_get_suspend_state();
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifndef DISABLE_SYNC_TIMER
 | 
			
		||||
    serial_m2s_buffer.sync_timer   = sync_timer_read32() + SYNC_TIMER_OFFSET;
 | 
			
		||||
#    endif
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
 | 
			
		||||
    transport_rgblight_slave();
 | 
			
		||||
#    ifndef DISABLE_SYNC_TIMER
 | 
			
		||||
    sync_timer_update(serial_m2s_buffer.sync_timer);
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    // TODO: if MATRIX_COLS > 8 change to pack()
 | 
			
		||||
    for (int i = 0; i < ROWS_PER_HAND; ++i) {
 | 
			
		||||
        serial_s2m_buffer.smatrix[i] = slave_matrix[i];
 | 
			
		||||
#    ifdef SPLIT_TRANSPORT_MIRROR
 | 
			
		||||
        master_matrix[i]             = serial_m2s_buffer.mmatrix[i];
 | 
			
		||||
#    endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#    ifdef BACKLIGHT_ENABLE
 | 
			
		||||
    backlight_set(serial_m2s_buffer.backlight_level);
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef ENCODER_ENABLE
 | 
			
		||||
    encoder_state_raw((uint8_t *)serial_s2m_buffer.encoder_state);
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef WPM_ENABLE
 | 
			
		||||
    set_current_wpm(serial_m2s_buffer.current_wpm);
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef SPLIT_MODS_ENABLE
 | 
			
		||||
    set_mods(serial_m2s_buffer.real_mods);
 | 
			
		||||
    set_weak_mods(serial_m2s_buffer.weak_mods);
 | 
			
		||||
#        ifndef NO_ACTION_ONESHOT
 | 
			
		||||
    set_oneshot_mods(serial_m2s_buffer.oneshot_mods);
 | 
			
		||||
#        endif
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    ifdef POINTING_DEVICE_ENABLE
 | 
			
		||||
    if (!is_keyboard_left()) {
 | 
			
		||||
        static uint16_t cpi;
 | 
			
		||||
        if (cpi != serial_m2s_buffer.device_cpi) {
 | 
			
		||||
            cpi = serial_m2s_buffer.device_cpi;
 | 
			
		||||
            pmw_set_cpi(cpi);
 | 
			
		||||
        }
 | 
			
		||||
        serial_s2m_buffer.mouse_x = split_mouse_x;
 | 
			
		||||
        serial_s2m_buffer.mouse_y = split_mouse_y;
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
    if (layer_state != serial_m2s_buffer.t_layer_state) {
 | 
			
		||||
        layer_state = serial_m2s_buffer.t_layer_state;
 | 
			
		||||
    }
 | 
			
		||||
    if (default_layer_state != serial_m2s_buffer.t_default_layer_state) {
 | 
			
		||||
        default_layer_state = serial_m2s_buffer.t_default_layer_state;
 | 
			
		||||
    }
 | 
			
		||||
#    ifdef OLED_DRIVER_ENABLE
 | 
			
		||||
    if (serial_m2s_buffer.oled_on) {
 | 
			
		||||
        oled_on();
 | 
			
		||||
    } else {
 | 
			
		||||
        oled_off();
 | 
			
		||||
    }
 | 
			
		||||
#    endif
 | 
			
		||||
 | 
			
		||||
#    if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
 | 
			
		||||
    led_matrix_eeconfig = serial_m2s_buffer.led_matrix;
 | 
			
		||||
    led_matrix_set_suspend_state(serial_m2s_buffer.led_suspend_state);
 | 
			
		||||
#    endif
 | 
			
		||||
#    if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
 | 
			
		||||
    rgb_matrix_config = serial_m2s_buffer.rgb_matrix;
 | 
			
		||||
    rgb_matrix_set_suspend_state(serial_m2s_buffer.rgb_suspend_state);
 | 
			
		||||
#    endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,7 @@
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
uint32_t        oled_timer                       = 0;
 | 
			
		||||
static char     keylog_str[KEYLOGGER_LENGTH + 1] = {"\n"};
 | 
			
		||||
static char     keylog_str[KEYLOGGER_LENGTH + 1] = { 0 };
 | 
			
		||||
static uint16_t log_timer                        = 0;
 | 
			
		||||
 | 
			
		||||
// clang-format off
 | 
			
		||||
| 
						 | 
				
			
			@ -57,12 +57,12 @@ void add_keylog(uint16_t keycode) {
 | 
			
		|||
        keycode = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (uint8_t i = (KEYLOGGER_LENGTH - 1); i > 0; --i) {
 | 
			
		||||
        keylog_str[i] = keylog_str[i - 1];
 | 
			
		||||
    for (uint8_t i = 1; i < KEYLOGGER_LENGTH; i++) {
 | 
			
		||||
        keylog_str[i-1] = keylog_str[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (keycode < (sizeof(code_to_name) / sizeof(char))) {
 | 
			
		||||
        keylog_str[0] = pgm_read_byte(&code_to_name[keycode]);
 | 
			
		||||
        keylog_str[(KEYLOGGER_LENGTH - 1)] = pgm_read_byte(&code_to_name[keycode]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    log_timer = timer_read();
 | 
			
		||||
| 
						 | 
				
			
			@ -92,30 +92,14 @@ void render_keylogger_status(void) {
 | 
			
		|||
void render_default_layer_state(void) {
 | 
			
		||||
    oled_write_P(PSTR(OLED_RENDER_LAYOUT_NAME), false);
 | 
			
		||||
    switch (get_highest_layer(default_layer_state)) {
 | 
			
		||||
        case _QWERTY:
 | 
			
		||||
            oled_write_P(PSTR(OLED_RENDER_LAYOUT_QWERTY), false);
 | 
			
		||||
            break;
 | 
			
		||||
        case _COLEMAK:
 | 
			
		||||
            oled_write_P(PSTR(OLED_RENDER_LAYOUT_COLEMAK), false);
 | 
			
		||||
            break;
 | 
			
		||||
        case _DVORAK:
 | 
			
		||||
            oled_write_P(PSTR(OLED_RENDER_LAYOUT_DVORAK), false);
 | 
			
		||||
            break;
 | 
			
		||||
        case _WORKMAN:
 | 
			
		||||
            oled_write_P(PSTR(OLED_RENDER_LAYOUT_WORKMAN), false);
 | 
			
		||||
            break;
 | 
			
		||||
        case _NORMAN:
 | 
			
		||||
            oled_write_P(PSTR(OLED_RENDER_LAYOUT_NORMAN), false);
 | 
			
		||||
            break;
 | 
			
		||||
        case _MALTRON:
 | 
			
		||||
            oled_write_P(PSTR(OLED_RENDER_LAYOUT_MALTRON), false);
 | 
			
		||||
            break;
 | 
			
		||||
        case _EUCALYN:
 | 
			
		||||
            oled_write_P(PSTR(OLED_RENDER_LAYOUT_EUCALYN), false);
 | 
			
		||||
            break;
 | 
			
		||||
        case _CARPLAX:
 | 
			
		||||
            oled_write_P(PSTR(OLED_RENDER_LAYOUT_CARPLAX), false);
 | 
			
		||||
            break;
 | 
			
		||||
        case _QWERTY: oled_write_P(PSTR(OLED_RENDER_LAYOUT_QWERTY), false); break;
 | 
			
		||||
        case _COLEMAK: oled_write_P(PSTR(OLED_RENDER_LAYOUT_COLEMAK), false); break;
 | 
			
		||||
        case _DVORAK: oled_write_P(PSTR(OLED_RENDER_LAYOUT_DVORAK), false); break;
 | 
			
		||||
        case _WORKMAN: oled_write_P(PSTR(OLED_RENDER_LAYOUT_WORKMAN), false); break;
 | 
			
		||||
        case _NORMAN: oled_write_P(PSTR(OLED_RENDER_LAYOUT_NORMAN), false); break;
 | 
			
		||||
        case _MALTRON: oled_write_P(PSTR(OLED_RENDER_LAYOUT_MALTRON), false); break;
 | 
			
		||||
        case _EUCALYN: oled_write_P(PSTR(OLED_RENDER_LAYOUT_EUCALYN), false); break;
 | 
			
		||||
        case _CARPLAX: oled_write_P(PSTR(OLED_RENDER_LAYOUT_CARPLAX), false); break;
 | 
			
		||||
    }
 | 
			
		||||
#ifdef OLED_DISPLAY_128X64
 | 
			
		||||
    oled_advance_page(true);
 | 
			
		||||
| 
						 | 
				
			
			@ -159,12 +143,12 @@ void render_keylock_status(uint8_t led_usb_state) {
 | 
			
		|||
}
 | 
			
		||||
void render_matrix_scan_rate(void) {
 | 
			
		||||
#ifdef DEBUG_MATRIX_SCAN_RATE
 | 
			
		||||
    char matrix_rate[5];
 | 
			
		||||
    uint16_t n = get_matrix_scan_rate();
 | 
			
		||||
    char     matrix_rate[5];
 | 
			
		||||
    uint16_t n     = get_matrix_scan_rate();
 | 
			
		||||
    matrix_rate[4] = '\0';
 | 
			
		||||
    matrix_rate[3] = '0' + n % 10;
 | 
			
		||||
    matrix_rate[2] = ( n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
 | 
			
		||||
    matrix_rate[1] =  n / 10 ? '0' + n / 10 : ' ';
 | 
			
		||||
    matrix_rate[2] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
 | 
			
		||||
    matrix_rate[1] = n / 10 ? '0' + n / 10 : ' ';
 | 
			
		||||
    matrix_rate[0] = ' ';
 | 
			
		||||
    oled_write_P(PSTR("MS:"), false);
 | 
			
		||||
    oled_write(matrix_rate, false);
 | 
			
		||||
| 
						 | 
				
			
			@ -284,6 +268,10 @@ void render_user_status(void) {
 | 
			
		|||
    oled_write_P(rgb_layer_status[userspace_config.rgb_layer_change], false);
 | 
			
		||||
    static const char PROGMEM nukem_good[2][3] = {{0xF8, 0xF9, 0}, {0xF6, 0xF7, 0}};
 | 
			
		||||
    oled_write_P(nukem_good[0], userspace_config.nuke_switch);
 | 
			
		||||
#if defined(UNICODE_ENABLE)
 | 
			
		||||
    static const char PROGMEM uc_mod_status[5][3] = {{0xEA, 0xEB, 0}, {0xEC, 0xED, 0}};
 | 
			
		||||
    oled_write_P(uc_mod_status[get_unicode_input_mode() == UC_MAC], false);
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(OLED_DISPLAY_128X64)
 | 
			
		||||
    oled_advance_page(true);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -306,34 +294,34 @@ void render_wpm(void) {
 | 
			
		|||
    char wpm_counter[4];
 | 
			
		||||
    wpm_counter[3] = '\0';
 | 
			
		||||
    wpm_counter[2] = '0' + n % 10;
 | 
			
		||||
    wpm_counter[1] = ( n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
 | 
			
		||||
    wpm_counter[1] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
 | 
			
		||||
    wpm_counter[0] = n / 10 ? '0' + n / 10 : ' ';
 | 
			
		||||
#    else
 | 
			
		||||
    char wpm_counter[6];
 | 
			
		||||
    wpm_counter[5] = '\0';
 | 
			
		||||
    wpm_counter[4] = '0' + n % 10;
 | 
			
		||||
    wpm_counter[3] = ( n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
 | 
			
		||||
    wpm_counter[3] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
 | 
			
		||||
    wpm_counter[2] = n / 10 ? '0' + n / 10 : ' ';
 | 
			
		||||
    wpm_counter[1] = ' ';
 | 
			
		||||
    wpm_counter[0] = ' ';
 | 
			
		||||
    #    endif
 | 
			
		||||
#    endif
 | 
			
		||||
    oled_write_P(PSTR(OLED_RENDER_WPM_COUNTER), false);
 | 
			
		||||
    oled_write(wpm_counter, false);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef KEYBOARD_handwired_dactyl_manuform_5x6_right_trackball
 | 
			
		||||
#if defined(KEYBOARD_handwired_tractyl_manuform_5x6_right)
 | 
			
		||||
extern keyboard_config_t keyboard_config;
 | 
			
		||||
extern uint16_t          dpi_array[];
 | 
			
		||||
 | 
			
		||||
void render_pointing_dpi_status(void) {
 | 
			
		||||
    char dpi_status[6];
 | 
			
		||||
    uint16_t n = dpi_array[keyboard_config.dpi_config];
 | 
			
		||||
    char     dpi_status[6];
 | 
			
		||||
    uint16_t n    = dpi_array[keyboard_config.dpi_config];
 | 
			
		||||
    dpi_status[5] = '\0';
 | 
			
		||||
    dpi_status[4] = '0' + n % 10;
 | 
			
		||||
    dpi_status[3] = ( n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
 | 
			
		||||
    dpi_status[2] = ( n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
 | 
			
		||||
    dpi_status[1] =  n / 10 ? '0' + n / 10 : ' ';
 | 
			
		||||
    dpi_status[3] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
 | 
			
		||||
    dpi_status[2] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
 | 
			
		||||
    dpi_status[1] = n / 10 ? '0' + n / 10 : ' ';
 | 
			
		||||
    dpi_status[0] = ' ';
 | 
			
		||||
    oled_write_P(PSTR("  DPI: "), false);
 | 
			
		||||
    oled_write(dpi_status, false);
 | 
			
		||||
| 
						 | 
				
			
			@ -360,7 +348,7 @@ void render_status_main(void) {
 | 
			
		|||
#    else
 | 
			
		||||
    render_wpm();
 | 
			
		||||
#    endif
 | 
			
		||||
#    ifdef KEYBOARD_handwired_dactyl_manuform_5x6_right_trackball
 | 
			
		||||
#    if defined(KEYBOARD_handwired_tractyl_manuform_5x6_right)
 | 
			
		||||
    render_pointing_dpi_status();
 | 
			
		||||
#    endif
 | 
			
		||||
    oled_write_P(PSTR("\n"), false);
 | 
			
		||||
| 
						 | 
				
			
			@ -375,6 +363,15 @@ void render_status_main(void) {
 | 
			
		|||
    render_keylogger_status();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) oled_rotation_t oled_init_keymap(oled_rotation_t rotation) { return rotation; }
 | 
			
		||||
 | 
			
		||||
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
 | 
			
		||||
    for (uint8_t i = 0; i < (KEYLOGGER_LENGTH - 1); i++) {
 | 
			
		||||
        add_keylog(0);
 | 
			
		||||
    }
 | 
			
		||||
    return oled_init_keymap(rotation);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void oled_task_user(void) {
 | 
			
		||||
    update_log();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -385,7 +382,7 @@ void oled_task_user(void) {
 | 
			
		|||
        } else {
 | 
			
		||||
            oled_on();
 | 
			
		||||
        }
 | 
			
		||||
        render_status_main();  // Renders the current keyboard state (layer, lock, caps, scroll, etc)
 | 
			
		||||
        render_status_main(); // Renders the current keyboard state (layer, lock, caps, scroll, etc)
 | 
			
		||||
    } else {
 | 
			
		||||
        render_status_secondary();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,97 +19,98 @@
 | 
			
		|||
#include "quantum.h"
 | 
			
		||||
#include "oled_driver.h"
 | 
			
		||||
 | 
			
		||||
void oled_driver_render_logo(void);
 | 
			
		||||
bool process_record_user_oled(uint16_t keycode, keyrecord_t *record);
 | 
			
		||||
void            oled_driver_render_logo(void);
 | 
			
		||||
bool            process_record_user_oled(uint16_t keycode, keyrecord_t *record);
 | 
			
		||||
oled_rotation_t oled_init_keymap(oled_rotation_t rotation);
 | 
			
		||||
extern uint32_t oled_timer;
 | 
			
		||||
 | 
			
		||||
#ifdef OLED_DISPLAY_128X64
 | 
			
		||||
#    define OLED_RENDER_KEYLOGGER "Keylogger: "
 | 
			
		||||
#    define OLED_RENDER_KEYLOGGER         "Keylogger: "
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_NAME    "Layout: "
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_QWERTY  "Qwerty"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_COLEMAK "Colemak"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_DVORAK  "Dvorak"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_WORKMAN "Workman"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_NORMAN  "Norman"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_MALTRON "Matron"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_EUCALYN "Eucalyn"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_CARPLAX "Carplax"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_NAME       "Layout: "
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_QWERTY     "Qwerty"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_COLEMAK    "Colemak"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_DVORAK     "Dvorak"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_WORKMAN    "Workman"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_NORMAN     "Norman"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_MALTRON    "Matron"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_EUCALYN    "Eucalyn"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_CARPLAX    "Carplax"
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_LAYER_NAME   "Layer:"
 | 
			
		||||
#    define OLED_RENDER_LAYER_LOWER  "Lower"
 | 
			
		||||
#    define OLED_RENDER_LAYER_RAISE  "Raise"
 | 
			
		||||
#    define OLED_RENDER_LAYER_ADJUST "Adjust"
 | 
			
		||||
#    define OLED_RENDER_LAYER_MODS   "Mods"
 | 
			
		||||
#    define OLED_RENDER_LAYER_NAME        "Layer:"
 | 
			
		||||
#    define OLED_RENDER_LAYER_LOWER       "Lower"
 | 
			
		||||
#    define OLED_RENDER_LAYER_RAISE       "Raise"
 | 
			
		||||
#    define OLED_RENDER_LAYER_ADJUST      "Adjust"
 | 
			
		||||
#    define OLED_RENDER_LAYER_MODS        "Mods"
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_LOCK_NAME "Lock: "
 | 
			
		||||
#    define OLED_RENDER_LOCK_NUML "NUML"
 | 
			
		||||
#    define OLED_RENDER_LOCK_CAPS "CAPS"
 | 
			
		||||
#    define OLED_RENDER_LOCK_SCLK "SCLK"
 | 
			
		||||
#    define OLED_RENDER_LOCK_NAME         "Lock: "
 | 
			
		||||
#    define OLED_RENDER_LOCK_NUML         "NUML"
 | 
			
		||||
#    define OLED_RENDER_LOCK_CAPS         "CAPS"
 | 
			
		||||
#    define OLED_RENDER_LOCK_SCLK         "SCLK"
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_MODS_NAME "Mods:"
 | 
			
		||||
#    define OLED_RENDER_MODS_SFT  "Sft"
 | 
			
		||||
#    define OLED_RENDER_MODS_CTL  "Ctl"
 | 
			
		||||
#    define OLED_RENDER_MODS_ALT  "Alt"
 | 
			
		||||
#    define OLED_RENDER_MODS_GUI  "GUI"
 | 
			
		||||
#    define OLED_RENDER_MODS_NAME         "Mods:"
 | 
			
		||||
#    define OLED_RENDER_MODS_SFT          "Sft"
 | 
			
		||||
#    define OLED_RENDER_MODS_CTL          "Ctl"
 | 
			
		||||
#    define OLED_RENDER_MODS_ALT          "Alt"
 | 
			
		||||
#    define OLED_RENDER_MODS_GUI          "GUI"
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_NAME  "Boot  "
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_NKRO  "NKRO"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_NOGUI "nGUI"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_GRV   "GRV"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_NAME    "Boot  "
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_NKRO    "NKRO"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_NOGUI   "nGUI"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_GRV     "GRV"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_ONESHOT "1SHT"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_SWAP "SWAP"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_CAPS  "CAPS"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_SWAP    "SWAP"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_CAPS    "CAPS"
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_USER_NAME "USER:"
 | 
			
		||||
#    define OLED_RENDER_USER_ANIM "Anim"
 | 
			
		||||
#    define OLED_RENDER_USER_LAYR "Layr"
 | 
			
		||||
#    define OLED_RENDER_USER_NUKE "Nuke"
 | 
			
		||||
#    define OLED_RENDER_USER_NAME         "USER:"
 | 
			
		||||
#    define OLED_RENDER_USER_ANIM         "Anim"
 | 
			
		||||
#    define OLED_RENDER_USER_LAYR         "Layr"
 | 
			
		||||
#    define OLED_RENDER_USER_NUKE         "Nuke"
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_WPM_COUNTER "WPM: "
 | 
			
		||||
#    define OLED_RENDER_WPM_COUNTER       "WPM: "
 | 
			
		||||
#else
 | 
			
		||||
#    define OLED_RENDER_KEYLOGGER "KLogr"
 | 
			
		||||
#    define OLED_RENDER_KEYLOGGER         "KLogr"
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_NAME    "Lyout"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_QWERTY  " QRTY"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_COLEMAK " COLE"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_DVORAK  " DVRK"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_WORKMAN " WKMN"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_NORMAN  " NORM"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_MALTRON " MLTN"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_EUCALYN " ECLN"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_CARPLAX " CRPX"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_NAME       "Lyout"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_QWERTY     " QRTY"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_COLEMAK    " COLE"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_DVORAK     " DVRK"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_WORKMAN    " WKMN"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_NORMAN     " NORM"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_MALTRON    " MLTN"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_EUCALYN    " ECLN"
 | 
			
		||||
#    define OLED_RENDER_LAYOUT_CARPLAX    " CRPX"
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_LAYER_NAME   "LAYER"
 | 
			
		||||
#    define OLED_RENDER_LAYER_LOWER  "Lower"
 | 
			
		||||
#    define OLED_RENDER_LAYER_RAISE  "Raise"
 | 
			
		||||
#    define OLED_RENDER_LAYER_ADJUST "Adjst"
 | 
			
		||||
#    define OLED_RENDER_LAYER_MODS   " Mods"
 | 
			
		||||
#    define OLED_RENDER_LAYER_NAME        "LAYER"
 | 
			
		||||
#    define OLED_RENDER_LAYER_LOWER       "Lower"
 | 
			
		||||
#    define OLED_RENDER_LAYER_RAISE       "Raise"
 | 
			
		||||
#    define OLED_RENDER_LAYER_ADJUST      "Adjst"
 | 
			
		||||
#    define OLED_RENDER_LAYER_MODS        " Mods"
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_LOCK_NAME "Lock:"
 | 
			
		||||
#    define OLED_RENDER_LOCK_NUML "NumL"
 | 
			
		||||
#    define OLED_RENDER_LOCK_CAPS "CapL"
 | 
			
		||||
#    define OLED_RENDER_LOCK_SCLK "ScrL"
 | 
			
		||||
#    define OLED_RENDER_LOCK_NAME         "Lock:"
 | 
			
		||||
#    define OLED_RENDER_LOCK_NUML         "NumL"
 | 
			
		||||
#    define OLED_RENDER_LOCK_CAPS         "CapL"
 | 
			
		||||
#    define OLED_RENDER_LOCK_SCLK         "ScrL"
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_MODS_NAME "Mods: "
 | 
			
		||||
#    define OLED_RENDER_MODS_SFT  "Shft"
 | 
			
		||||
#    define OLED_RENDER_MODS_CTL  "Ctrl"
 | 
			
		||||
#    define OLED_RENDER_MODS_ALT  "Alt\n"
 | 
			
		||||
#    define OLED_RENDER_MODS_GUI  "GUI\n"
 | 
			
		||||
#    define OLED_RENDER_MODS_NAME         "Mods: "
 | 
			
		||||
#    define OLED_RENDER_MODS_SFT          "Shft"
 | 
			
		||||
#    define OLED_RENDER_MODS_CTL          "Ctrl"
 | 
			
		||||
#    define OLED_RENDER_MODS_ALT          "Alt\n"
 | 
			
		||||
#    define OLED_RENDER_MODS_GUI          "GUI\n"
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_NAME  "BTMGK"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_NKRO  "NKRO"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_NOGUI "nGUI"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_GRV   "GRV"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_NAME    "BTMGK"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_NKRO    "NKRO"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_NOGUI   "nGUI"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_GRV     "GRV"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_ONESHOT "1SHT"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_SWAP "SWAP"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_CAPS  "CAPS"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_SWAP    "SWAP"
 | 
			
		||||
#    define OLED_RENDER_BOOTMAGIC_CAPS    "CAPS"
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_USER_NAME "USER:"
 | 
			
		||||
#    define OLED_RENDER_USER_ANIM "Anim"
 | 
			
		||||
#    define OLED_RENDER_USER_LAYR "Layr"
 | 
			
		||||
#    define OLED_RENDER_USER_NUKE "Nuke"
 | 
			
		||||
#    define OLED_RENDER_USER_NAME         "USER:"
 | 
			
		||||
#    define OLED_RENDER_USER_ANIM         "Anim"
 | 
			
		||||
#    define OLED_RENDER_USER_LAYR         "Layr"
 | 
			
		||||
#    define OLED_RENDER_USER_NUKE         "Nuke"
 | 
			
		||||
 | 
			
		||||
#    define OLED_RENDER_WPM_COUNTER "WPM: "
 | 
			
		||||
#    define OLED_RENDER_WPM_COUNTER       "WPM: "
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,10 +29,10 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
    // If console is enabled, it will print the matrix position and status of each key pressed
 | 
			
		||||
#ifdef KEYLOGGER_ENABLE
 | 
			
		||||
    uprintf("KL: kc: 0x%04X, col: %2u, row: %2u, pressed: %b, time: %5u, int: %b, count: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed, record->event.time, record->tap.interrupted, record->tap.count);
 | 
			
		||||
#endif  // KEYLOGGER_ENABLE
 | 
			
		||||
#endif // KEYLOGGER_ENABLE
 | 
			
		||||
#ifdef OLED_DRIVER_ENABLE
 | 
			
		||||
    process_record_user_oled(keycode, record);
 | 
			
		||||
#endif  // OLED
 | 
			
		||||
#endif // OLED
 | 
			
		||||
 | 
			
		||||
    if (!(process_record_keymap(keycode, record) && process_record_secrets(keycode, record)
 | 
			
		||||
#ifdef RGB_MATRIX_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -59,7 +59,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case KC_MAKE:  // Compiles the firmware, and adds the flash command based on keyboard bootloader
 | 
			
		||||
        case KC_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader
 | 
			
		||||
            if (!record->event.pressed) {
 | 
			
		||||
#ifndef MAKE_BOOTLOADER
 | 
			
		||||
                uint8_t temp_mod = mod_config(get_mods());
 | 
			
		||||
| 
						 | 
				
			
			@ -90,56 +90,44 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case VRSN:  // Prints firmware version
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY);
 | 
			
		||||
            }
 | 
			
		||||
        case VRSN: // Prints firmware version
 | 
			
		||||
            if (record->event.pressed) { send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY); }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case KC_DIABLO_CLEAR:  // reset all Diablo timers, disabling them
 | 
			
		||||
        case KC_DIABLO_CLEAR: // reset all Diablo timers, disabling them
 | 
			
		||||
#ifdef TAP_DANCE_ENABLE
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                for (uint8_t index = 0; index < 4; index++) {
 | 
			
		||||
                    diablo_timer[index].key_interval = 0;
 | 
			
		||||
                }
 | 
			
		||||
                for (uint8_t index = 0; index < 4; index++) { diablo_timer[index].key_interval = 0; }
 | 
			
		||||
            }
 | 
			
		||||
#endif  // TAP_DANCE_ENABLE
 | 
			
		||||
#endif // TAP_DANCE_ENABLE
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case KC_CCCV:  // One key copy/paste
 | 
			
		||||
        case KC_CCCV: // One key copy/paste
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                copy_paste_timer = timer_read();
 | 
			
		||||
            } else {
 | 
			
		||||
                if (timer_elapsed(copy_paste_timer) > TAPPING_TERM) {  // Hold, copy
 | 
			
		||||
                if (timer_elapsed(copy_paste_timer) > TAPPING_TERM) { // Hold, copy
 | 
			
		||||
                    tap_code16(LCTL(KC_C));
 | 
			
		||||
                } else {  // Tap, paste
 | 
			
		||||
                } else { // Tap, paste
 | 
			
		||||
                    tap_code16(LCTL(KC_V));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
#ifdef UNICODE_ENABLE
 | 
			
		||||
        case UC_FLIP:  // (ノಠ痊ಠ)ノ彡┻━┻
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                send_unicode_string("(ノಠ痊ಠ)ノ彡┻━┻");
 | 
			
		||||
            }
 | 
			
		||||
        case UC_FLIP: // (ノಠ痊ಠ)ノ彡┻━┻
 | 
			
		||||
            if (record->event.pressed) { send_unicode_string("(ノಠ痊ಠ)ノ彡┻━┻"); }
 | 
			
		||||
            break;
 | 
			
		||||
        case UC_TABL:  // ┬─┬ノ( º _ ºノ)
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                send_unicode_string("┬─┬ノ( º _ ºノ)");
 | 
			
		||||
            }
 | 
			
		||||
        case UC_TABL: // ┬─┬ノ( º _ ºノ)
 | 
			
		||||
            if (record->event.pressed) { send_unicode_string("┬─┬ノ( º _ ºノ)"); }
 | 
			
		||||
            break;
 | 
			
		||||
        case UC_SHRG:  // ¯\_(ツ)_/¯
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                send_unicode_string("¯\\_(ツ)_/¯");
 | 
			
		||||
            }
 | 
			
		||||
        case UC_SHRG: // ¯\_(ツ)_/¯
 | 
			
		||||
            if (record->event.pressed) { send_unicode_string("¯\\_(ツ)_/¯"); }
 | 
			
		||||
            break;
 | 
			
		||||
        case UC_DISA:  // ಠ_ಠ
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                send_unicode_string("ಠ_ಠ");
 | 
			
		||||
            }
 | 
			
		||||
        case UC_DISA: // ಠ_ಠ
 | 
			
		||||
            if (record->event.pressed) { send_unicode_string("ಠ_ಠ"); }
 | 
			
		||||
            break;
 | 
			
		||||
#endif
 | 
			
		||||
        case KC_RGB_T:  // This allows me to use underglow as layer indication, or as normal
 | 
			
		||||
        case KC_RGB_T: // This allows me to use underglow as layer indication, or as normal
 | 
			
		||||
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                userspace_config.rgb_layer_change ^= 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -149,14 +137,14 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
#    if defined(RGBLIGHT_ENABLE) && defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
                    rgblight_enable_noeeprom();
 | 
			
		||||
#    endif
 | 
			
		||||
                    layer_state_set(layer_state);  // This is needed to immediately set the layer color (looks better)
 | 
			
		||||
                    layer_state_set(layer_state); // This is needed to immediately set the layer color (looks better)
 | 
			
		||||
#    if defined(RGBLIGHT_ENABLE) && defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
                } else {
 | 
			
		||||
                    rgblight_disable_noeeprom();
 | 
			
		||||
#    endif
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
#endif  // RGBLIGHT_ENABLE
 | 
			
		||||
#endif // RGBLIGHT_ENABLE
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
 | 
			
		||||
| 
						 | 
				
			
			@ -176,7 +164,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
            break;
 | 
			
		||||
        case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT:  // quantum_keycodes.h L400 for definitions
 | 
			
		||||
        case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // quantum_keycodes.h L400 for definitions
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                bool is_eeprom_updated;
 | 
			
		||||
#    if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)
 | 
			
		||||
| 
						 | 
				
			
			@ -194,9 +182,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
                    is_eeprom_updated = true;
 | 
			
		||||
                }
 | 
			
		||||
#    endif
 | 
			
		||||
                if (is_eeprom_updated) {
 | 
			
		||||
                    eeconfig_update_user(userspace_config.raw);
 | 
			
		||||
                }
 | 
			
		||||
                if (is_eeprom_updated) { eeconfig_update_user(userspace_config.raw); }
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,58 +17,58 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
#include "drashna.h"
 | 
			
		||||
 | 
			
		||||
#if defined(KEYBOARD_handwired_dactyl_manuform_5x6_right_trackball)
 | 
			
		||||
#if defined(KEYBOARD_handwired_tractyl_manuform_5x6_right)
 | 
			
		||||
#    define PLACEHOLDER_SAFE_RANGE KEYMAP_SAFE_RANGE
 | 
			
		||||
#else
 | 
			
		||||
#    define PLACEHOLDER_SAFE_RANGE SAFE_RANGE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
enum userspace_custom_keycodes {
 | 
			
		||||
    VRSN = PLACEHOLDER_SAFE_RANGE,  // Prints QMK Firmware and board info
 | 
			
		||||
    KC_QWERTY,                      // Sets default layer to QWERTY
 | 
			
		||||
    KC_COLEMAK,                     // Sets default layer to COLEMAK
 | 
			
		||||
    KC_DVORAK,                      // Sets default layer to DVORAK
 | 
			
		||||
    KC_WORKMAN,                     // Sets default layer to WORKMAN
 | 
			
		||||
    KC_DIABLO_CLEAR,                // Clears all Diablo Timers
 | 
			
		||||
    KC_MAKE,                        // Run keyboard's customized make command
 | 
			
		||||
    KC_RGB_T,                       // Toggles RGB Layer Indication mode
 | 
			
		||||
    RGB_IDL,                        // RGB Idling animations
 | 
			
		||||
    KC_SECRET_1,                    // test1
 | 
			
		||||
    KC_SECRET_2,                    // test2
 | 
			
		||||
    KC_SECRET_3,                    // test3
 | 
			
		||||
    KC_SECRET_4,                    // test4
 | 
			
		||||
    KC_SECRET_5,                    // test5
 | 
			
		||||
    KC_CCCV,                        // Hold to copy, tap to paste
 | 
			
		||||
    KC_NUKE,                        // NUCLEAR LAUNCH DETECTED!!!
 | 
			
		||||
    UC_FLIP,                        // (ಠ痊ಠ)┻━┻
 | 
			
		||||
    UC_TABL,                        // ┬─┬ノ( º _ ºノ)
 | 
			
		||||
    UC_SHRG,                        // ¯\_(ツ)_/¯
 | 
			
		||||
    UC_DISA,                        // ಠ_ಠ
 | 
			
		||||
    NEW_SAFE_RANGE                  // use "NEWPLACEHOLDER for keymap specific codes
 | 
			
		||||
    VRSN = PLACEHOLDER_SAFE_RANGE, // Prints QMK Firmware and board info
 | 
			
		||||
    KC_QWERTY,                     // Sets default layer to QWERTY
 | 
			
		||||
    KC_COLEMAK,                    // Sets default layer to COLEMAK
 | 
			
		||||
    KC_DVORAK,                     // Sets default layer to DVORAK
 | 
			
		||||
    KC_WORKMAN,                    // Sets default layer to WORKMAN
 | 
			
		||||
    KC_DIABLO_CLEAR,               // Clears all Diablo Timers
 | 
			
		||||
    KC_MAKE,                       // Run keyboard's customized make command
 | 
			
		||||
    KC_RGB_T,                      // Toggles RGB Layer Indication mode
 | 
			
		||||
    RGB_IDL,                       // RGB Idling animations
 | 
			
		||||
    KC_SECRET_1,                   // test1
 | 
			
		||||
    KC_SECRET_2,                   // test2
 | 
			
		||||
    KC_SECRET_3,                   // test3
 | 
			
		||||
    KC_SECRET_4,                   // test4
 | 
			
		||||
    KC_SECRET_5,                   // test5
 | 
			
		||||
    KC_CCCV,                       // Hold to copy, tap to paste
 | 
			
		||||
    KC_NUKE,                       // NUCLEAR LAUNCH DETECTED!!!
 | 
			
		||||
    UC_FLIP,                       // (ಠ痊ಠ)┻━┻
 | 
			
		||||
    UC_TABL,                       // ┬─┬ノ( º _ ºノ)
 | 
			
		||||
    UC_SHRG,                       // ¯\_(ツ)_/¯
 | 
			
		||||
    UC_DISA,                       // ಠ_ಠ
 | 
			
		||||
    NEW_SAFE_RANGE                 // use "NEWPLACEHOLDER for keymap specific codes
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool process_record_secrets(uint16_t keycode, keyrecord_t *record);
 | 
			
		||||
bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
 | 
			
		||||
 | 
			
		||||
#define LOWER   MO(_LOWER)
 | 
			
		||||
#define RAISE   MO(_RAISE)
 | 
			
		||||
#define ADJUST  MO(_ADJUST)
 | 
			
		||||
#define TG_MODS OS_TOGG
 | 
			
		||||
#define TG_GAME TG(_GAMEPAD)
 | 
			
		||||
#define TG_DBLO TG(_DIABLO)
 | 
			
		||||
#define OS_LWR  OSL(_LOWER)
 | 
			
		||||
#define OS_RSE  OSL(_RAISE)
 | 
			
		||||
#define LOWER    MO(_LOWER)
 | 
			
		||||
#define RAISE    MO(_RAISE)
 | 
			
		||||
#define ADJUST   MO(_ADJUST)
 | 
			
		||||
#define TG_MODS  OS_TOGG
 | 
			
		||||
#define TG_GAME  TG(_GAMEPAD)
 | 
			
		||||
#define TG_DBLO  TG(_DIABLO)
 | 
			
		||||
#define OS_LWR   OSL(_LOWER)
 | 
			
		||||
#define OS_RSE   OSL(_RAISE)
 | 
			
		||||
 | 
			
		||||
#define KC_SEC1 KC_SECRET_1
 | 
			
		||||
#define KC_SEC2 KC_SECRET_2
 | 
			
		||||
#define KC_SEC3 KC_SECRET_3
 | 
			
		||||
#define KC_SEC4 KC_SECRET_4
 | 
			
		||||
#define KC_SEC5 KC_SECRET_5
 | 
			
		||||
#define KC_SEC1  KC_SECRET_1
 | 
			
		||||
#define KC_SEC2  KC_SECRET_2
 | 
			
		||||
#define KC_SEC3  KC_SECRET_3
 | 
			
		||||
#define KC_SEC4  KC_SECRET_4
 | 
			
		||||
#define KC_SEC5  KC_SECRET_5
 | 
			
		||||
 | 
			
		||||
#define QWERTY  KC_QWERTY
 | 
			
		||||
#define DVORAK  KC_DVORAK
 | 
			
		||||
#define COLEMAK KC_COLEMAK
 | 
			
		||||
#define WORKMAN KC_WORKMAN
 | 
			
		||||
#define QWERTY   KC_QWERTY
 | 
			
		||||
#define DVORAK   KC_DVORAK
 | 
			
		||||
#define COLEMAK  KC_COLEMAK
 | 
			
		||||
#define WORKMAN  KC_WORKMAN
 | 
			
		||||
 | 
			
		||||
#define KC_RESET RESET
 | 
			
		||||
#define KC_RST   KC_RESET
 | 
			
		||||
| 
						 | 
				
			
			@ -77,9 +77,9 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record);
 | 
			
		|||
#    define KC_C1R3 SH_T(KC_TAB)
 | 
			
		||||
#elif defined(DRASHNA_LP)
 | 
			
		||||
#    define KC_C1R3 TG(_GAMEPAD)
 | 
			
		||||
#else  // SWAP_HANDS_ENABLE
 | 
			
		||||
#else // SWAP_HANDS_ENABLE
 | 
			
		||||
#    define KC_C1R3 KC_TAB
 | 
			
		||||
#endif  // SWAP_HANDS_ENABLE
 | 
			
		||||
#endif // SWAP_HANDS_ENABLE
 | 
			
		||||
 | 
			
		||||
#define BK_LWER LT(_LOWER, KC_BSPC)
 | 
			
		||||
#define SP_LWER LT(_LOWER, KC_SPC)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,33 +28,27 @@ static uint32_t hypno_timer;
 | 
			
		|||
 | 
			
		||||
void rgb_matrix_layer_helper(uint8_t hue, uint8_t sat, uint8_t val, uint8_t mode, uint8_t speed, uint8_t led_type, uint8_t led_min, uint8_t led_max) {
 | 
			
		||||
    HSV hsv = {hue, sat, val};
 | 
			
		||||
    if (hsv.v > rgb_matrix_get_val()) {
 | 
			
		||||
        hsv.v = rgb_matrix_get_val();
 | 
			
		||||
    }
 | 
			
		||||
    if (hsv.v > rgb_matrix_get_val()) { hsv.v = rgb_matrix_get_val(); }
 | 
			
		||||
 | 
			
		||||
    switch (mode) {
 | 
			
		||||
        case 1:  // breathing
 | 
			
		||||
        {
 | 
			
		||||
            uint16_t time = scale16by8(g_rgb_timer, speed / 8);
 | 
			
		||||
            hsv.v         = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
 | 
			
		||||
            RGB rgb       = hsv_to_rgb(hsv);
 | 
			
		||||
            for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
 | 
			
		||||
                if (HAS_FLAGS(g_led_config.flags[i], led_type)) {
 | 
			
		||||
                    RGB_MATRIX_INDICATOR_SET_COLOR(i, rgb.r, rgb.g, rgb.b);
 | 
			
		||||
        case 1: // breathing
 | 
			
		||||
            {
 | 
			
		||||
                uint16_t time = scale16by8(g_rgb_timer, speed / 8);
 | 
			
		||||
                hsv.v         = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
 | 
			
		||||
                RGB rgb       = hsv_to_rgb(hsv);
 | 
			
		||||
                for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
 | 
			
		||||
                    if (HAS_FLAGS(g_led_config.flags[i], led_type)) { RGB_MATRIX_INDICATOR_SET_COLOR(i, rgb.r, rgb.g, rgb.b); }
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        default:  // Solid Color
 | 
			
		||||
        {
 | 
			
		||||
            RGB rgb = hsv_to_rgb(hsv);
 | 
			
		||||
            for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
 | 
			
		||||
                if (HAS_FLAGS(g_led_config.flags[i], led_type)) {
 | 
			
		||||
                    RGB_MATRIX_INDICATOR_SET_COLOR(i, rgb.r, rgb.g, rgb.b);
 | 
			
		||||
        default: // Solid Color
 | 
			
		||||
            {
 | 
			
		||||
                RGB rgb = hsv_to_rgb(hsv);
 | 
			
		||||
                for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
 | 
			
		||||
                    if (HAS_FLAGS(g_led_config.flags[i], led_type)) { RGB_MATRIX_INDICATOR_SET_COLOR(i, rgb.r, rgb.g, rgb.b); }
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -62,38 +56,30 @@ __attribute__((weak)) void rgb_matrix_indicator_keymap(void) {}
 | 
			
		|||
 | 
			
		||||
void matrix_scan_rgb_matrix(void) {
 | 
			
		||||
#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
 | 
			
		||||
    if (userspace_config.rgb_matrix_idle_anim && rgb_matrix_get_mode() == RGB_MATRIX_TYPING_HEATMAP && sync_timer_elapsed32(hypno_timer) > 15000) {
 | 
			
		||||
        rgb_matrix_mode_noeeprom(RGB_MATRIX_REST_MODE);
 | 
			
		||||
    }
 | 
			
		||||
    if (userspace_config.rgb_matrix_idle_anim && rgb_matrix_get_mode() == RGB_MATRIX_TYPING_HEATMAP && sync_timer_elapsed32(hypno_timer) > 15000) { rgb_matrix_mode_noeeprom(RGB_MATRIX_REST_MODE); }
 | 
			
		||||
#endif
 | 
			
		||||
    rgb_matrix_indicator_keymap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void keyboard_post_init_rgb_matrix(void) {
 | 
			
		||||
#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
 | 
			
		||||
    if (userspace_config.rgb_matrix_idle_anim) {
 | 
			
		||||
        rgb_matrix_mode_noeeprom(RGB_MATRIX_REST_MODE);
 | 
			
		||||
    }
 | 
			
		||||
    if (userspace_config.rgb_matrix_idle_anim) { rgb_matrix_mode_noeeprom(RGB_MATRIX_REST_MODE); }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool process_record_user_rgb_matrix(uint16_t keycode, keyrecord_t *record) {
 | 
			
		||||
#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
 | 
			
		||||
    hypno_timer = sync_timer_read32();
 | 
			
		||||
    if (userspace_config.rgb_matrix_idle_anim && rgb_matrix_get_mode() == RGB_MATRIX_REST_MODE) {
 | 
			
		||||
        rgb_matrix_mode_noeeprom(RGB_MATRIX_TYPING_HEATMAP);
 | 
			
		||||
    }
 | 
			
		||||
    if (userspace_config.rgb_matrix_idle_anim && rgb_matrix_get_mode() == RGB_MATRIX_REST_MODE) { rgb_matrix_mode_noeeprom(RGB_MATRIX_TYPING_HEATMAP); }
 | 
			
		||||
#endif
 | 
			
		||||
    switch (keycode) {
 | 
			
		||||
        case RGB_IDL:  // This allows me to use underglow as layer indication, or as normal
 | 
			
		||||
        case RGB_IDL: // This allows me to use underglow as layer indication, or as normal
 | 
			
		||||
#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS)
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                userspace_config.rgb_matrix_idle_anim ^= 1;
 | 
			
		||||
                dprintf("RGB Matrix Idle Animation [EEPROM]: %u\n", userspace_config.rgb_matrix_idle_anim);
 | 
			
		||||
                eeconfig_update_user(userspace_config.raw);
 | 
			
		||||
                if (userspace_config.rgb_matrix_idle_anim) {
 | 
			
		||||
                    rgb_matrix_mode_noeeprom(RGB_MATRIX_TYPING_HEATMAP);
 | 
			
		||||
                }
 | 
			
		||||
                if (userspace_config.rgb_matrix_idle_anim) { rgb_matrix_mode_noeeprom(RGB_MATRIX_TYPING_HEATMAP); }
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
            break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,7 +28,7 @@ void rgblight_sethsv_default_helper(uint8_t index) { rgblight_sethsv_at(rgblight
 | 
			
		|||
static rgblight_fadeout lights[RGBLED_NUM];
 | 
			
		||||
 | 
			
		||||
/* Handler for fading/twinkling effect */
 | 
			
		||||
void scan_rgblight_fadeout(void) {  // Don't effing change this function .... rgblight_sethsv is supppppper intensive
 | 
			
		||||
void scan_rgblight_fadeout(void) { // Don't effing change this function .... rgblight_sethsv is supppppper intensive
 | 
			
		||||
    bool litup = false;
 | 
			
		||||
 | 
			
		||||
    for (uint8_t light_index = 0; light_index < RGBLED_NUM; ++light_index) {
 | 
			
		||||
| 
						 | 
				
			
			@ -38,21 +38,15 @@ void scan_rgblight_fadeout(void) {  // Don't effing change this function .... rg
 | 
			
		|||
 | 
			
		||||
            if (light->life) {
 | 
			
		||||
                light->life -= 1;
 | 
			
		||||
                if (get_highest_layer(layer_state) == 0) {
 | 
			
		||||
                    sethsv(light->hue + rand() % 0xF, 255, light->life, (LED_TYPE *)&led[light_index]);
 | 
			
		||||
                }
 | 
			
		||||
                if (get_highest_layer(layer_state) == 0) { sethsv(light->hue + rand() % 0xF, 255, light->life, (LED_TYPE *)&led[light_index]); }
 | 
			
		||||
                light->timer = sync_timer_read();
 | 
			
		||||
            } else {
 | 
			
		||||
                if (light->enabled && get_highest_layer(layer_state) == 0) {
 | 
			
		||||
                    rgblight_sethsv_default_helper(light_index);
 | 
			
		||||
                }
 | 
			
		||||
                if (light->enabled && get_highest_layer(layer_state) == 0) { rgblight_sethsv_default_helper(light_index); }
 | 
			
		||||
                litup = light->enabled = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (litup && get_highest_layer(layer_state) == 0) {
 | 
			
		||||
        rgblight_set();
 | 
			
		||||
    }
 | 
			
		||||
    if (litup && get_highest_layer(layer_state) == 0) { rgblight_set(); }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Triggers a LED to fade/twinkle.
 | 
			
		||||
| 
						 | 
				
			
			@ -98,9 +92,7 @@ void start_rgb_light(void) {
 | 
			
		|||
bool process_record_user_rgb_light(uint16_t keycode, keyrecord_t *record) {
 | 
			
		||||
    uint16_t temp_keycode = keycode;
 | 
			
		||||
    // Filter out the actual keycode from MT and LT keys.
 | 
			
		||||
    if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) {
 | 
			
		||||
        temp_keycode &= 0xFF;
 | 
			
		||||
    }
 | 
			
		||||
    if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) { temp_keycode &= 0xFF; }
 | 
			
		||||
 | 
			
		||||
    switch (temp_keycode) {
 | 
			
		||||
#    ifdef RGBLIGHT_TWINKLE
 | 
			
		||||
| 
						 | 
				
			
			@ -110,11 +102,9 @@ bool process_record_user_rgb_light(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
        case KC_KP_SLASH ... KC_KP_DOT:
 | 
			
		||||
        case KC_F13 ... KC_F24:
 | 
			
		||||
        case KC_AUDIO_MUTE ... KC_MEDIA_REWIND:
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                start_rgb_light();
 | 
			
		||||
            }
 | 
			
		||||
            if (record->event.pressed) { start_rgb_light(); }
 | 
			
		||||
            break;
 | 
			
		||||
#    endif  // RGBLIGHT_TWINKLE
 | 
			
		||||
#    endif // RGBLIGHT_TWINKLE
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -129,9 +119,7 @@ static uint16_t rgblight_startup_loop_timer;
 | 
			
		|||
void keyboard_post_init_rgb_light(void) {
 | 
			
		||||
#    if defined(RGBLIGHT_STARTUP_ANIMATION)
 | 
			
		||||
    is_enabled = rgblight_is_enabled();
 | 
			
		||||
    if (userspace_config.rgb_layer_change) {
 | 
			
		||||
        rgblight_enable_noeeprom();
 | 
			
		||||
    }
 | 
			
		||||
    if (userspace_config.rgb_layer_change) { rgblight_enable_noeeprom(); }
 | 
			
		||||
    if (rgblight_is_enabled()) {
 | 
			
		||||
        layer_state_set_rgb_light(layer_state);
 | 
			
		||||
        old_hue = rgblight_get_hue();
 | 
			
		||||
| 
						 | 
				
			
			@ -145,7 +133,7 @@ void keyboard_post_init_rgb_light(void) {
 | 
			
		|||
void matrix_scan_rgb_light(void) {
 | 
			
		||||
#    ifdef RGBLIGHT_TWINKLE
 | 
			
		||||
    scan_rgblight_fadeout();
 | 
			
		||||
#    endif  // RGBLIGHT_ENABLE
 | 
			
		||||
#    endif // RGBLIGHT_ENABLE
 | 
			
		||||
 | 
			
		||||
#    if defined(RGBLIGHT_STARTUP_ANIMATION)
 | 
			
		||||
    if (is_rgblight_startup && is_keyboard_master()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -156,12 +144,8 @@ void matrix_scan_rgb_light(void) {
 | 
			
		|||
            rgblight_startup_loop_timer = sync_timer_read();
 | 
			
		||||
            if (counter == 255) {
 | 
			
		||||
                is_rgblight_startup = false;
 | 
			
		||||
                if (!is_enabled) {
 | 
			
		||||
                    rgblight_disable_noeeprom();
 | 
			
		||||
                }
 | 
			
		||||
                if (userspace_config.rgb_layer_change) {
 | 
			
		||||
                    layer_state_set_rgb_light(layer_state);
 | 
			
		||||
                }
 | 
			
		||||
                if (!is_enabled) { rgblight_disable_noeeprom(); }
 | 
			
		||||
                if (userspace_config.rgb_layer_change) { layer_state_set_rgb_light(layer_state); }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -179,55 +163,25 @@ layer_state_t layer_state_set_rgb_light(layer_state_t state) {
 | 
			
		|||
    if (userspace_config.rgb_layer_change) {
 | 
			
		||||
        switch (get_highest_layer(state | default_layer_state)) {
 | 
			
		||||
            case _MACROS: // mouse
 | 
			
		||||
                if (!layer_state_cmp(state, _GAMEPAD) && !layer_state_cmp(state, _DIABLO)) {
 | 
			
		||||
                    rgblight_set_hsv_and_mode(HSV_CHARTREUSE, RGBLIGHT_MODE_BREATHING + 3);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case _MEDIA:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_CHARTREUSE, RGBLIGHT_MODE_KNIGHT + 1);
 | 
			
		||||
                break;
 | 
			
		||||
            case _GAMEPAD:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_ORANGE, RGBLIGHT_MODE_SNAKE + 2);
 | 
			
		||||
                break;
 | 
			
		||||
            case _DIABLO:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_RED, RGBLIGHT_MODE_BREATHING + 3);
 | 
			
		||||
                break;
 | 
			
		||||
            case _RAISE:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_YELLOW, RGBLIGHT_MODE_BREATHING + 3);
 | 
			
		||||
                break;
 | 
			
		||||
            case _LOWER:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_GREEN, RGBLIGHT_MODE_BREATHING + 3);
 | 
			
		||||
                break;
 | 
			
		||||
            case _ADJUST:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_RED, RGBLIGHT_MODE_KNIGHT + 2);
 | 
			
		||||
                break;
 | 
			
		||||
            case _COLEMAK:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_MAGENTA, RGBLIGHT_MODE_STATIC_LIGHT);
 | 
			
		||||
                break;
 | 
			
		||||
            case _DVORAK:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_SPRINGGREEN, RGBLIGHT_MODE_STATIC_LIGHT);
 | 
			
		||||
                break;
 | 
			
		||||
            case _WORKMAN:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_GOLDENROD, RGBLIGHT_MODE_STATIC_LIGHT);
 | 
			
		||||
                break;
 | 
			
		||||
            case _NORMAN:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_CORAL, RGBLIGHT_MODE_STATIC_LIGHT);
 | 
			
		||||
                break;
 | 
			
		||||
            case _MALTRON:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_YELLOW, RGBLIGHT_MODE_STATIC_LIGHT);
 | 
			
		||||
                break;
 | 
			
		||||
            case _EUCALYN:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_PINK, RGBLIGHT_MODE_STATIC_LIGHT);
 | 
			
		||||
                break;
 | 
			
		||||
            case _CARPLAX:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_BLUE, RGBLIGHT_MODE_STATIC_LIGHT);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                rgblight_set_hsv_and_mode(HSV_CYAN, RGBLIGHT_MODE_STATIC_LIGHT);
 | 
			
		||||
                if (!layer_state_cmp(state, _GAMEPAD) && !layer_state_cmp(state, _DIABLO)) { rgblight_set_hsv_and_mode(HSV_CHARTREUSE, RGBLIGHT_MODE_BREATHING + 3); }
 | 
			
		||||
                break;
 | 
			
		||||
            case _MEDIA: rgblight_set_hsv_and_mode(HSV_CHARTREUSE, RGBLIGHT_MODE_KNIGHT + 1); break;
 | 
			
		||||
            case _GAMEPAD: rgblight_set_hsv_and_mode(HSV_ORANGE, RGBLIGHT_MODE_SNAKE + 2); break;
 | 
			
		||||
            case _DIABLO: rgblight_set_hsv_and_mode(HSV_RED, RGBLIGHT_MODE_BREATHING + 3); break;
 | 
			
		||||
            case _RAISE: rgblight_set_hsv_and_mode(HSV_YELLOW, RGBLIGHT_MODE_BREATHING + 3); break;
 | 
			
		||||
            case _LOWER: rgblight_set_hsv_and_mode(HSV_GREEN, RGBLIGHT_MODE_BREATHING + 3); break;
 | 
			
		||||
            case _ADJUST: rgblight_set_hsv_and_mode(HSV_RED, RGBLIGHT_MODE_KNIGHT + 2); break;
 | 
			
		||||
            case _COLEMAK: rgblight_set_hsv_and_mode(HSV_MAGENTA, RGBLIGHT_MODE_STATIC_LIGHT); break;
 | 
			
		||||
            case _DVORAK: rgblight_set_hsv_and_mode(HSV_SPRINGGREEN, RGBLIGHT_MODE_STATIC_LIGHT); break;
 | 
			
		||||
            case _WORKMAN: rgblight_set_hsv_and_mode(HSV_GOLDENROD, RGBLIGHT_MODE_STATIC_LIGHT); break;
 | 
			
		||||
            case _NORMAN: rgblight_set_hsv_and_mode(HSV_CORAL, RGBLIGHT_MODE_STATIC_LIGHT); break;
 | 
			
		||||
            case _MALTRON: rgblight_set_hsv_and_mode(HSV_YELLOW, RGBLIGHT_MODE_STATIC_LIGHT); break;
 | 
			
		||||
            case _EUCALYN: rgblight_set_hsv_and_mode(HSV_PINK, RGBLIGHT_MODE_STATIC_LIGHT); break;
 | 
			
		||||
            case _CARPLAX: rgblight_set_hsv_and_mode(HSV_BLUE, RGBLIGHT_MODE_STATIC_LIGHT); break;
 | 
			
		||||
            default: rgblight_set_hsv_and_mode(HSV_CYAN, RGBLIGHT_MODE_STATIC_LIGHT); break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#    endif  // RGBLIGHT_ENABLE
 | 
			
		||||
#    endif // RGBLIGHT_ENABLE
 | 
			
		||||
 | 
			
		||||
    return state;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,28 +80,29 @@ endif
 | 
			
		|||
 | 
			
		||||
CUSTOM_SPLIT_TRANSPORT ?= yes
 | 
			
		||||
ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
 | 
			
		||||
    ifneq ($(strip $(SPLIT_TRANSPORT)), custom)
 | 
			
		||||
        ifeq ($(strip $(CUSTOM_SPLIT_TRANSPORT)), yes)
 | 
			
		||||
            SPLIT_TRANSPORT = custom
 | 
			
		||||
            QUANTUM_LIB_SRC += drashna_transport.c
 | 
			
		||||
            OPT_DEFS += -DDRASHNA_CUSTOM_TRANSPORT
 | 
			
		||||
            # Unused functions are pruned away, which is why we can add multiple drivers here without bloat.
 | 
			
		||||
            ifeq ($(PLATFORM),AVR)
 | 
			
		||||
                ifneq ($(NO_I2C),yes)
 | 
			
		||||
                    QUANTUM_LIB_SRC += i2c_master.c \
 | 
			
		||||
                                    i2c_slave.c
 | 
			
		||||
                endif
 | 
			
		||||
            endif
 | 
			
		||||
    QUANTUM_LIB_SRC += transport_sync.c
 | 
			
		||||
    # ifneq ($(strip $(SPLIT_TRANSPORT)), custom)
 | 
			
		||||
    #     ifeq ($(strip $(CUSTOM_SPLIT_TRANSPORT)), yes)
 | 
			
		||||
    #         SPLIT_TRANSPORT = custom
 | 
			
		||||
    #         QUANTUM_LIB_SRC += drashna_transport.c
 | 
			
		||||
    #         OPT_DEFS += -DDRASHNA_CUSTOM_TRANSPORT
 | 
			
		||||
    #         # Unused functions are pruned away, which is why we can add multiple drivers here without bloat.
 | 
			
		||||
    #         ifeq ($(PLATFORM),AVR)
 | 
			
		||||
    #             ifneq ($(NO_I2C),yes)
 | 
			
		||||
    #                 QUANTUM_LIB_SRC += i2c_master.c \
 | 
			
		||||
    #                                 i2c_slave.c
 | 
			
		||||
    #             endif
 | 
			
		||||
    #         endif
 | 
			
		||||
 | 
			
		||||
            SERIAL_DRIVER ?= bitbang
 | 
			
		||||
            OPT_DEFS += -DSERIAL_DRIVER_$(strip $(shell echo $(SERIAL_DRIVER) | tr '[:lower:]' '[:upper:]'))
 | 
			
		||||
            ifeq ($(strip $(SERIAL_DRIVER)), bitbang)
 | 
			
		||||
                QUANTUM_LIB_SRC += serial.c
 | 
			
		||||
            else
 | 
			
		||||
                QUANTUM_LIB_SRC += serial_$(strip $(SERIAL_DRIVER)).c
 | 
			
		||||
            endif
 | 
			
		||||
        endif
 | 
			
		||||
    endif
 | 
			
		||||
    #         SERIAL_DRIVER ?= bitbang
 | 
			
		||||
    #         OPT_DEFS += -DSERIAL_DRIVER_$(strip $(shell echo $(SERIAL_DRIVER) | tr '[:lower:]' '[:upper:]'))
 | 
			
		||||
    #         ifeq ($(strip $(SERIAL_DRIVER)), bitbang)
 | 
			
		||||
    #             QUANTUM_LIB_SRC += serial.c
 | 
			
		||||
    #         else
 | 
			
		||||
    #             QUANTUM_LIB_SRC += serial_$(strip $(SERIAL_DRIVER)).c
 | 
			
		||||
    #         endif
 | 
			
		||||
    #     endif
 | 
			
		||||
    # endif
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# DEBUG_MATRIX_SCAN_RATE_ENABLE = api
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ uint8_t diablo_times[] = {0, 1, 3, 5, 10, 30};
 | 
			
		|||
 | 
			
		||||
// Cycle through the times for the macro, starting at 0, for disabled.
 | 
			
		||||
void diablo_tapdance_master(qk_tap_dance_state_t *state, void *user_data) {
 | 
			
		||||
    diable_keys_t *diablo_keys = (diable_keys_t *)user_data;
 | 
			
		||||
    diable_keys_t *diablo_keys               = (diable_keys_t *)user_data;
 | 
			
		||||
    // Sets the keycode based on the index
 | 
			
		||||
    diablo_timer[diablo_keys->index].keycode = diablo_keys->keycode;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +34,7 @@ void diablo_tapdance_master(qk_tap_dance_state_t *state, void *user_data) {
 | 
			
		|||
    if (state->count >= (sizeof(diablo_times) / sizeof(uint8_t))) {
 | 
			
		||||
        diablo_timer[diablo_keys->index].key_interval = 0;
 | 
			
		||||
        reset_tap_dance(state);
 | 
			
		||||
    } else {  // else set the interval (tapdance count starts at 1, array starts at 0, so offset by one)
 | 
			
		||||
    } else { // else set the interval (tapdance count starts at 1, array starts at 0, so offset by one)
 | 
			
		||||
        diablo_timer[diablo_keys->index].key_interval = diablo_times[state->count - 1];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -64,9 +64,7 @@ void run_diablo_macro_check(void) {
 | 
			
		|||
            // reset the timer, since enough time has passed
 | 
			
		||||
            diablo_timer[index].timer = timer_read();
 | 
			
		||||
            // send keycode ONLY if we're on the diablo layer.
 | 
			
		||||
            if (IS_LAYER_ON(_DIABLO)) {
 | 
			
		||||
                tap_code(diablo_timer[index].keycode);
 | 
			
		||||
            }
 | 
			
		||||
            if (IS_LAYER_ON(_DIABLO)) { tap_code(diablo_timer[index].keycode); }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,4 +43,4 @@ enum {
 | 
			
		|||
    TD_D3_4
 | 
			
		||||
};
 | 
			
		||||
// clang-format on
 | 
			
		||||
#endif  // TAP_DANCE_ENABLE
 | 
			
		||||
#endif // TAP_DANCE_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,9 +54,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		|||
            break;
 | 
			
		||||
 | 
			
		||||
        case VRSN:
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
 | 
			
		||||
            }
 | 
			
		||||
            if (record->event.pressed) { SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION); }
 | 
			
		||||
            return false;
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +87,7 @@ __attribute__((weak)) void startup_keymap(void) {}
 | 
			
		|||
void startup_user(void) {
 | 
			
		||||
#ifdef RGBLIGHT_ENABLE
 | 
			
		||||
    matrix_init_rgb();
 | 
			
		||||
#endif  // RGBLIGHT_ENABLE
 | 
			
		||||
#endif // RGBLIGHT_ENABLE
 | 
			
		||||
    startup_keymap();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,8 +24,8 @@
 | 
			
		|||
#define BASE 0
 | 
			
		||||
 | 
			
		||||
enum custom_keycodes {
 | 
			
		||||
    VRSN = SAFE_RANGE,  // can always be here
 | 
			
		||||
    VRSN = SAFE_RANGE, // can always be here
 | 
			
		||||
    KC_MAKE,
 | 
			
		||||
    KC_RESET,
 | 
			
		||||
    NEWPLACEHOLDER  // use "NEWPLACEHOLDER for keymap specific codes
 | 
			
		||||
    NEWPLACEHOLDER // use "NEWPLACEHOLDER for keymap specific codes
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										80
									
								
								users/drashna/transport_sync.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								users/drashna/transport_sync.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
#ifdef SPLIT_TRANSACTION_IDS_USER
 | 
			
		||||
#include "transport_sync.h"
 | 
			
		||||
#include "transactions.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    bool            oled_on;
 | 
			
		||||
    uint16_t keymap_config;
 | 
			
		||||
} user_runtime_config_t;
 | 
			
		||||
 | 
			
		||||
user_runtime_config_t user_state;
 | 
			
		||||
 | 
			
		||||
void user_sync(uint8_t initiator2target_buffer_size, const void* initiator2target_buffer, uint8_t target2initiator_buffer_size, void* target2initiator_buffer) {
 | 
			
		||||
    if (initiator2target_buffer_size == sizeof(user_state)) {
 | 
			
		||||
        memcpy(&user_state, initiator2target_buffer, initiator2target_buffer_size);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void keyboard_post_init_transport_sync(void) {
 | 
			
		||||
    // Register keyboard state sync split transaction
 | 
			
		||||
    transaction_register_rpc(RPC_ID_USER_STATE_SYNC, user_sync);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void user_state_update(void) {
 | 
			
		||||
    if (is_keyboard_master()) {
 | 
			
		||||
 | 
			
		||||
#ifdef OLED_DRIVER_ENABLE
 | 
			
		||||
        user_state.oled_on = is_oled_on();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        user_state.keymap_config = keymap_config.raw;
 | 
			
		||||
    } else {
 | 
			
		||||
#ifdef OLED_DRIVER_ENABLE
 | 
			
		||||
        if (user_state.oled_on) {
 | 
			
		||||
            oled_on();
 | 
			
		||||
        } else {
 | 
			
		||||
            oled_off();
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        if (keymap_config.raw != user_state.keymap_config) {
 | 
			
		||||
            keymap_config.raw = user_state.keymap_config;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void user_state_sync(void) {
 | 
			
		||||
    if (is_keyboard_master()) {
 | 
			
		||||
        // Keep track of the last state, so that we can tell if we need to propagate to slave
 | 
			
		||||
        static user_runtime_config_t last_user_state;
 | 
			
		||||
        static uint32_t              last_sync;
 | 
			
		||||
        bool                         needs_sync = false;
 | 
			
		||||
 | 
			
		||||
        // Check if the state values are different
 | 
			
		||||
        if (memcmp(&user_state, &last_user_state, sizeof(user_state))) {
 | 
			
		||||
            needs_sync = true;
 | 
			
		||||
            memcpy(&last_user_state, &user_state, sizeof(user_state));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Send to slave every 500ms regardless of state change
 | 
			
		||||
        if (timer_elapsed32(last_sync) > 250) {
 | 
			
		||||
            needs_sync = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Perform the sync if requested
 | 
			
		||||
        if (needs_sync) {
 | 
			
		||||
            if (transaction_rpc_send(RPC_ID_USER_STATE_SYNC, sizeof(user_state), &user_state)) {
 | 
			
		||||
                last_sync = timer_read32();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void housekeeping_task_user(void) {
 | 
			
		||||
    // Update kb_state so we can send to slave
 | 
			
		||||
    user_state_update();
 | 
			
		||||
 | 
			
		||||
    // Data sync from master to slave
 | 
			
		||||
    user_state_sync();
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										22
									
								
								users/drashna/transport_sync.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								users/drashna/transport_sync.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
 | 
			
		||||
/* Copyright 2020 Christopher Courtney, aka Drashna Jael're  (@drashna) <drashna@live.com>
 | 
			
		||||
 *
 | 
			
		||||
 * 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/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "drashna.h"
 | 
			
		||||
 | 
			
		||||
void keyboard_post_init_transport_sync(void);
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue