~ruther/qmk_firmware

ee6a0e8744fa8bde6a2e5fba398d963b0a776cdd — QMK Bot 3 years ago 35fa0f2 + 98da119
Merge remote-tracking branch 'origin/master' into develop
A keyboards/preonic/keymaps/era1112/config.h => keyboards/preonic/keymaps/era1112/config.h +60 -0
@@ 0,0 1,60 @@
// Copyright 2022 Era James(@Era1112)
// SPDX - License - Identifier: GPL - 2.0 - or -later

#pragma once


//----------- Default statements -----------//
//------------------------------------------//
#define MUSIC_MASK (keycode < 0xFF)

/*
 * MIDI options
 */

/* enable basic MIDI features:
   - MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC

/* enable advanced MIDI features:
   - MIDI notes can be added to the keymap
   - Octave shift and transpose
   - Virtual sustain, portamento, and modulation wheel
   - etc.
*/
#define MIDI_ADVANCED

/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2


//----------- Added statements -------------//
//------------------------------------------//
#define TAPPING_TERM 200                        // For tapdances

// Commented to see if it helps stalls on clicky mode #define DYNAMIC_MACRO_NO_NESTING                // Improve dynamic macro stability
#ifdef AUDIO_ENABLE
	#define AUDIO_INIT_DELAY                    // to make startup audio work
	#define STARTUP_SONG SONG(PREONIC_SOUND)
	#define AUDIO_CLICKY                        // enable clicky mode

	// Clicky mode parameters
	#define AUDIO_CLICKY_FREQ_MIN 65.0f         // Default 65
	#define AUDIO_CLICKY_FREQ_DEFAULT 800.0f    // Default 440
	#define AUDIO_CLICKY_FREQ_MAX 1500.0f       // Defaul 1500
	#define AUDIO_CLICKY_FREQ_RANDOMNESS 1.0f   // Default 0.05
	#define AUDIO_CLICKY_DELAY_DURATION 0.1f    // Default 1
#endif  //AUDIO_ENABLE

#define RGBLIGHT_SLEEP                  // RGB lights turn off when host sleeps

// Firmware minimization

// Commented to see if it helps stalls on clicky mode 
// #define NO_ACTION_ONESHOT
// #undef LOCKING_SUPPORT_ENABLE
// #undef LOCKING_RESYNC_ENABLE
// #define NO_MUSIC_MODE
// #define LAYER_STATE_8BIT        // Limits keymap to 8 layers
// #undef RGBLIGHT_ANIMATIONS      // Removes rgb animations

A keyboards/preonic/keymaps/era1112/keymap.c => keyboards/preonic/keymaps/era1112/keymap.c +365 -0
@@ 0,0 1,365 @@
// Copyright 2022 Era James(@Era1112)
// SPDX - License - Identifier: GPL - 2.0 - or -later

#include QMK_KEYBOARD_H                     // Default statement

#define HSV_RETRO_CONSOLE   36, 150, 255    //HSV_YELLOW = 43, 255, 255


//----------- RGB Default Settings -----------//
//--------------------------------------------//
#ifdef RGBLIGHT_ENABLE

void keyboard_post_init_user(void) {
    rgblight_enable_noeeprom(); // Enables RGB, without saving settings
    rgblight_sethsv_noeeprom(HSV_RETRO_CONSOLE);
    rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
}

#endif  // RGBLIGHT_ENABLE

//----------- Layer names -----------//
//-----------------------------------//
enum preonic_layers {
  _QWERTY,
  _LOWER,
  _RAISE,
  _ADJUST,
};


//----------- Sounds -----------//
//------------------------------//
#ifdef AUDIO_ENABLE

    float capslockToggleSound[][2] = SONG(STARTUP_SOUND);
    float dynamicBufferRecordSound[][2] = SONG(STARTUP_SOUND);
    float dynamicBufferFullSound[][2] = SONG(GOODBYE_SOUND);

#endif  // AUDIO_ENABLE


//----------- Called when dynamic buffer full -----------//
//-------------------------------------------------------//
void backlight_toggle(void) {
#ifdef AUDIO_ENABLE

    PLAY_SONG(dynamicBufferFullSound);

#endif  // AUDIO_ENABLE
}


//----------- Tapdance prelims -----------//
//----------------------------------------//
typedef enum {
    TD_NONE,
    TD_UNKNOWN,
    TD_1_TAP,
    TD_1_HOLD,
    TD_2_TAP,
    TD_2_HOLD,
} td_state_t;

typedef struct {
    bool is_press_action;
    td_state_t state;
} td_tap_t;

td_state_t cur_dance(qk_tap_dance_state_t* state);

/* Return an integer that corresponds to what kind of tap dance should be executed.
 *
 * How to figure out tap dance state: interrupted and pressed.
 *
 * Interrupted: If the state of a dance dance is "interrupted", that means that another key has been hit
 *  under the tapping term. This is typically indicitive that you are trying to "tap" the key.
 *
 * Pressed: Whether or not the key is still being pressed. If this value is true, that means the tapping term
 *  has ended, but the key is still being pressed down. This generally means the key is being "held".
 *
 * One thing that is currenlty not possible with qmk software in regards to tap dance is to mimic the "permissive hold"
 *  feature. In general, advanced tap dances do not work well if they are used with commonly typed letters.
 *  For example "A". Tap dances are best used on non-letter keys that are not hit while typing letters.
 *
 * Good places to put an advanced tap dance:
 *  z,q,x,j,k,v,b, any function key, home/end, comma, semi-colon
 *
 * Criteria for "good placement" of a tap dance key:
 *  Not a key that is hit frequently in a sentence
 *  Not a key that is used frequently to double tap, for example 'tab' is often double tapped in a terminal, or
 *    in a web form. So 'tab' would be a poor choice for a tap dance.
 *  Letters used in common words as a double. For example 'p' in 'pepper'. If a tap dance function existed on the
 *    letter 'p', the word 'pepper' would be quite frustating to type.
 *
 * For the third point, there does exist the 'TD_DOUBLE_SINGLE_TAP', however this is not fully tested
 *
 */
td_state_t cur_dance(qk_tap_dance_state_t* state) {
    if (state->count == 1) {
        if (state->interrupted || !state->pressed) {
            return TD_1_TAP;
        // Key has not been interrupted, but the key is still held. Means you want to send a 'HOLD'.
        } else {
        return TD_1_HOLD;
        }
    } else if (state->count == 2) {
        // TD_DOUBLE_SINGLE_TAP is to distinguish between typing "pepper", and actually wanting a double tap
        // action when hitting 'pp'. Suggested use case for this return value is when you want to send two
        // keystrokes of the key, and not the 'double tap' action/macro.
        if (state->pressed) return TD_2_HOLD;
        else return TD_2_TAP;
    } else {
        return TD_UNKNOWN;
    }
}


//----------- 2tap capslock --------------//
//----------------------------------------//
void twoCapsLock_finished(qk_tap_dance_state_t* state, void* user_data);
void twoCapsLock_reset(qk_tap_dance_state_t* state, void* user_data);

static td_tap_t twoCapsLock_tap_state = {
    .is_press_action = true,
    .state = TD_NONE
};

void twoCapsLock_finished(qk_tap_dance_state_t* state, void* user_data) {
    twoCapsLock_tap_state.state = cur_dance(state);
    switch (twoCapsLock_tap_state.state) {
    case TD_NONE: register_code(KC_LSFT); break;
    case TD_UNKNOWN: register_code(KC_LSFT); break;
    case TD_1_TAP: register_code(KC_LSFT); break;
    case TD_1_HOLD: register_code(KC_LSFT); break;
    case TD_2_TAP:
        register_code(KC_CAPS);
#ifdef AUDIO_ENABLE
        PLAY_SONG(capslockToggleSound);
#endif  // AUDIO_ENABLE
        break;
    case TD_2_HOLD: register_code(KC_LSFT); break;      
    }
}

void twoCapsLock_reset(qk_tap_dance_state_t* state, void* user_data) {
    switch (twoCapsLock_tap_state.state) {
    case TD_UNKNOWN: unregister_code(KC_LSFT); break;
    case TD_NONE: unregister_code(KC_LSFT); break;
    case TD_1_TAP: unregister_code(KC_LSFT); break;
    case TD_1_HOLD: unregister_code(KC_LSFT); break;
    case TD_2_TAP:
        unregister_code(KC_CAPS);
#ifdef AUDIO_ENABLE
        PLAY_SONG(capslockToggleSound);
#endif  // AUDIO_ENABLE
        break;
    case TD_2_HOLD: unregister_code(KC_LSFT); break;
    }
    twoCapsLock_tap_state.state = TD_NONE;
}


//----------- Rotary Encoder --------------//
//----------------------------------------//
bool encoder_update_user(uint8_t index, bool clockwise) {
    if (layer_state_is(_QWERTY)) {
        if (clockwise) {
            tap_code(KC_WH_U);
        } else {
            tap_code(KC_WH_D);
        }
    }
    else if (layer_state_is(_LOWER)) {
        if (clockwise) {
            tap_code16(S(KC_F3));
        } else {
            tap_code(KC_F3);
        }
    } else if (layer_state_is(_RAISE)) {
        if (clockwise) {
            tap_code16(C(KC_Z));
        } else {
            tap_code16(C(KC_Y));
        }
    }
    return false;
}

//----------- Custom keycodes ------------//
//----------------------------------------//
enum {
    TD_2_CAPSLOCK
};

enum custom_keycodes {
    CU_BLNKON = SAFE_RANGE,
    CU_BLNKOFF,
    CU_RGBON,
    CU_RGBOFF,
    ENC_MODE
};

static bool blinky = false;         // Track blinky behavior on/off for keycode

qk_tap_dance_action_t tap_dance_actions[] = {
    [TD_2_CAPSLOCK] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, twoCapsLock_finished, twoCapsLock_reset)
};


//----------- Intercepts and overrides ------------//
//-------------------------------------=-----------//
bool process_record_user(uint16_t keycode, keyrecord_t* record) {
    switch (keycode) {
    // Turn RGB LEDs off
    case CU_RGBOFF:

        // If pressed
        if (record->event.pressed) {
            rgblight_sethsv_noeeprom(HSV_OFF);   
            return true;

        // If released
        } else {
            return true;
        }

    // Turn RGB LEDs on
    case CU_RGBON:

        // If pressed
        if (record->event.pressed) {
            rgblight_sethsv_noeeprom(HSV_RETRO_CONSOLE);  
            return true;

        // If released
        } else {
            return true;
        }

    // Turn blinky LEDs off
    case CU_BLNKOFF:

        // If pressed
        if (record->event.pressed) {
            blinky = false;
            return true;

        // If released
        } else {
            return true;
        }

    // Turn blinky LEDs on
    case CU_BLNKON:

        // If pressed
        if (record->event.pressed) {
            blinky = true;
            return true;

        // If released
        } else {
            return true;
        }

    // Sound when Dynamic recording started
    case DYN_REC_START1:

        // If pressed
        if (record->event.pressed) {
        #ifdef AUDIO_ENABLE
            PLAY_SONG(dynamicBufferRecordSound);
        #endif  // AUDIO_ENABLE
            return true; // Let QMK send the press/release events

        // If released
        } else {
            return true; // Let QMK send the press/release events
        }

    // Sound when Dynamic recording stopped
    case DYN_REC_STOP:

        // If pressed
        if (record->event.pressed) {
        #ifdef AUDIO_ENABLE
            PLAY_SONG(dynamicBufferFullSound); 
        #endif  // AUDIO_ENABLE
            return true; // Let QMK send the enter press/release events

        // If released
        } else {
            return true; // Let QMK send the press/release events
        }

    // Encoder Click
    case ENC_MODE:
        if (record->event.pressed) {
            if (layer_state_is(_QWERTY)) {
                tap_code(KC_BTN1);
                return false;
            } else if (layer_state_is(_LOWER)) {
                return false;
            } else if (layer_state_is(_RAISE)) {
                return false;
            }
        }


    // Adds blinks if blinky is on
    default:
        if (blinky == true) {
            rgblight_toggle();
        }

    return true; // Process all other keycodes normally

    }
}


//----------- Keymap ------------//
//-------------------------------//
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

    // main layer
    [_QWERTY] = LAYOUT_ortho_5x12 (
        // (Non-disabled top row), uncomment and replace if you want preonic-style instead of planck-style
        // KC_MINS,            KC_1,           KC_2,           KC_3,           KC_4,           KC_5,           KC_6,           KC_7,           KC_8,       KC_9,       KC_0,       KC_EQL,
		KC_NO,              KC_NO,          KC_NO,          KC_NO,          KC_NO,          KC_NO,          KC_NO,          KC_NO,          KC_NO,      KC_NO,      KC_NO,      KC_NO,
        KC_TAB,             KC_Q,           KC_W,           KC_E,           KC_R,           KC_T,           KC_Y,           KC_U,           KC_I,       KC_O,       KC_P,       KC_BSPC,
        KC_ESC,             KC_A,           KC_S,           KC_D,           KC_F,           KC_G,           KC_H,           KC_J,           KC_K,       KC_L,       KC_SCLN,    KC_ENT,
        KC_LSFT,            KC_Z,           KC_X,           KC_C,           KC_V,           KC_B,           KC_N,           KC_M,           KC_COMM,    KC_DOT,     KC_SLSH,    TD(TD_2_CAPSLOCK),
        ENC_MODE,           KC_LCTL,        KC_LGUI,        KC_LALT,        MO(_LOWER),     KC_SPC,         KC_SPC,         MO(_RAISE),     KC_LEFT,    KC_DOWN,    KC_UP,      KC_RGHT
    ),

    // lower key
    [_LOWER] = LAYOUT_ortho_5x12 (
        DYN_MACRO_PLAY1,    DYN_REC_START1, DYN_REC_STOP,   KC_TRNS,        KC_TRNS,        KC_TRNS,        KC_TRNS,        KC_TRNS,            KC_TRNS,        KC_TRNS,    KC_TRNS,    KC_TRNS,
        KC_TRNS,            KC_1,           KC_2,           KC_3,           KC_4,           KC_5,           KC_6,           KC_7,               KC_8,           KC_9,       KC_0,       KC_DEL,
        KC_BSPC,            KC_F1,          KC_F2,          KC_F3,          KC_F4,          KC_F5,          KC_F6,          KC_QUOT,            KC_GRV,         KC_LCBR,    KC_RCBR,    KC_TRNS,
        KC_TRNS,            KC_F7,          KC_F8,          KC_F9,          KC_F10,         KC_F11,         KC_F12,         KC_MINS,            KC_EQL,         KC_TRNS,    KC_BSLS,    KC_TRNS,
        KC_TRNS,            KC_TRNS,        KC_TRNS,        KC_TRNS,        KC_TRNS,        KC_TRNS,        KC_TRNS,        MO(_ADJUST),        KC_HOME,        KC_PGDN,    KC_PGUP,    KC_END
    ),

    // raise key
    [_RAISE] = LAYOUT_ortho_5x12 (
        DYN_MACRO_PLAY1,    DYN_REC_START1, DYN_REC_STOP,   KC_TRNS,        KC_TRNS,        KC_TRNS,        KC_TRNS,        KC_TRNS,            KC_TRNS,        KC_TRNS,    KC_TRNS,    KC_TRNS,
        KC_TRNS,            KC_EXLM,        KC_AT,          KC_HASH,        KC_DLR,         KC_PERC,        KC_CIRC,        KC_AMPR,            KC_ASTR,        KC_LPRN,    KC_RPRN,    KC_DEL,
        KC_DEL,             KC_F1,          KC_F2,          KC_F3,          KC_F4,          KC_F5,          KC_F6,          KC_DQUO,            KC_TILD,        KC_LBRC,    KC_RBRC,    KC_TRNS,
        KC_TRNS,            KC_F7,          KC_F8,          KC_F9,          KC_F10,         KC_F11,         KC_F12,         KC_UNDS,            KC_PLUS	,       KC_TRNS,    KC_PIPE,    KC_TRNS,
        KC_TRNS,            KC_TRNS,        KC_TRNS,        KC_TRNS,        MO(_ADJUST),    KC_TRNS,        KC_TRNS,        KC_TRNS,            KC_MUTE,        KC_VOLD,    KC_VOLU,    KC_F24
    ),

    // hardware adjust layer, raise+lower
    [_ADJUST] = LAYOUT_ortho_5x12 (
        AU_ON,              AU_OFF,          CK_ON,           CK_OFF,          KC_NO,           KC_NO,           KC_NO,       KC_NO,           KC_NO,       KC_NO,       KC_NO,       KC_NO,
																																															
        CU_RGBON,           CU_RGBOFF,       CU_BLNKON,       CU_BLNKOFF,      KC_NO,           KC_NO,           KC_NO,       KC_NO,           KC_NO,       KC_NO,       KC_NO,       KC_NO,
		KC_NO,              KC_NO,           KC_NO,           KC_NO,           KC_NO,           KC_NO,           KC_NO,       KC_NO,           KC_NO,       KC_NO,       KC_NO,       KC_NO,
        KC_NO,              KC_NO,           KC_NO,           KC_NO,           KC_NO,           KC_NO,           KC_NO,       KC_NO,           KC_NO,       KC_NO,       KC_NO,       KC_NO,
        KC_NO,              KC_NO,           KC_NO,           KC_NO,           KC_NO,           KC_NO,           KC_NO,       KC_NO,           KC_NO,       KC_NO,       KC_NO,       KC_NO
    )
    
};

A keyboards/preonic/keymaps/era1112/readme.md => keyboards/preonic/keymaps/era1112/readme.md +8 -0
@@ 0,0 1,8 @@
A preonic keymap that includes:
- doubletap tapdance for caps lock
- rotary encoder
- macro record/playback
- light on/off
- sound on/off
- blink-on-keypress w/ on/off keystroke
- beep-on-keypress w/ on/off keystroke (this has stability issues when typing fast, still trying to remediate)
\ No newline at end of file

A keyboards/preonic/keymaps/era1112/rules.mk => keyboards/preonic/keymaps/era1112/rules.mk +26 -0
@@ 0,0 1,26 @@
## Copyright 2022 Era James (@Era1112)
## SPDX-License-Identifier: GPL-2.0-or-later

# DEFAULT STATEMENTS
# ==================

SRC += muse.c


# ADDED STATEMENTS
# ================

AUDIO_ENABLE = yes          # Audio output on
TAP_DANCE_ENABLE = yes		# For double-tap tapdances
DYNAMIC_MACRO_ENABLE = yes	# For dynamuic macros
RGBLIGHT_ENABLE = yes		# For RGB lighting functions
ENCODER_ENABLE = yes		# For Rotary encoders


# Firmware minimization
# Commented to see if it helps stalls on clicky mode 													 
CONSOLE_ENABLE = no
#LTO_ENABLE = yes
SPACE_CADET_ENABLE = no
GRAVE_ESC_ENABLE = no 
MAGIC_ENABLE = no