]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Add a keymap for the Ergodox EZ meant to be used with a Bépo keyboard layout (French...
authormkende <mathias@kende.fr>
Thu, 14 Dec 2017 05:04:21 +0000 (06:04 +0100)
committerJack Humbert <jack.humb@gmail.com>
Thu, 14 Dec 2017 05:04:21 +0000 (00:04 -0500)
* Initial version of the Ergodox EZ Bépo keymap, TypeMatrix style.

* Update the readme file and add some handling of the keyboard LEDs.

* Toggling layer requires 2 taps.

* Remove a constant as it conflicts with an earier definition.

* Fix a typo in a type name.

* Fix the arrow layer that had a bad number.

* Second main version of my bepo keymap, after the tests of the first one.

* Fix the triggering of the function layer and the handling of the LED.

* Reduce the shining of the LEDs.

* Fix the swap layer (that required a keypress on the other side of the keyboard to be deactivated).

* Duplicate some of the mouse button for easy access.

* Move some of the secondary functions out of the center keys.

* Slightly slow down the mouse and mouse wheel.

* Update the comment and readme.md for the V2 of the keymap.

* Invert button 2 and 3 of the mouse. Really fix the SWAP layer.

* Test with the right alt modifier added as secondary function (on hold) of the space keys. The right alt key becomes a left alt one.

* Add specific shift/ctrl for the FN layer; move some mouse keys around to help with that.

* Remove one FN modifier-on-hold key that was not useful.

* Duplicate the FN layer inside the MOUSE layer.

* Add support (not tested yet) for macro recording and play on a single key as a tap dance.

* Allow to stop recording the macro by tapping once on the macro key (still un-tested).

* Add support for macro recording using some tap dance.

* shorten a comment.

* Reinstate the FN toggle on the percent key (so that there is an FN toggle on the right-hand-side).

* Fix some comments and update the link to the most up-to-date image.

* Small fix to the keymap images.

keyboards/ergodox_ez/keymaps/bepo_tm_style/config.h [new file with mode: 0755]
keyboards/ergodox_ez/keymaps/bepo_tm_style/keymap.c [new file with mode: 0755]
keyboards/ergodox_ez/keymaps/bepo_tm_style/readme.md [new file with mode: 0755]
keyboards/ergodox_ez/keymaps/bepo_tm_style/rules.mk [new file with mode: 0755]

diff --git a/keyboards/ergodox_ez/keymaps/bepo_tm_style/config.h b/keyboards/ergodox_ez/keymaps/bepo_tm_style/config.h
new file mode 100755 (executable)
index 0000000..11c81f2
--- /dev/null
@@ -0,0 +1,28 @@
+#include "../../config.h"
+
+// Sets good default for the speed of the mouse.
+#undef MOUSEKEY_INTERVAL
+#undef MOUSEKEY_DELAY
+#undef MOUSEKEY_TIME_TO_MAX
+#undef MOUSEKEY_MAX_SPEED
+
+#define MOUSEKEY_INTERVAL       20
+#define MOUSEKEY_DELAY          100
+#define MOUSEKEY_TIME_TO_MAX    60
+#define MOUSEKEY_MAX_SPEED      7
+
+#undef MOUSEKEY_WHEEL_MAX_SPEED
+#undef MOUSEKEY_WHEEL_TIME_TO_MAX
+#undef MOUSEKEY_WHEEL_DELAY
+
+#define MOUSEKEY_WHEEL_MAX_SPEED    5
+#define MOUSEKEY_WHEEL_TIME_TO_MAX  60
+#define MOUSEKEY_WHEEL_DELAY        100
+
+#undef TAPPING_TOGGLE
+#undef TAPPING_TERM
+#undef IGNORE_MOD_TAP_INTERRUPT
+
+#define TAPPING_TOGGLE  1
+#define TAPPING_TERM    150
+#define IGNORE_MOD_TAP_INTERRUPT
diff --git a/keyboards/ergodox_ez/keymaps/bepo_tm_style/keymap.c b/keyboards/ergodox_ez/keymaps/bepo_tm_style/keymap.c
new file mode 100755 (executable)
index 0000000..061c3eb
--- /dev/null
@@ -0,0 +1,353 @@
+// An Ergodox EZ keymap meant to be used with a bépo layout (FR ergonomic
+// layout, dvorak style). The overall design is slightly inspired by the
+// TypeMatrix keyboard. Switching between a TypeMatrix and an Ergodox with this
+// layout should be relatively easy.
+//
+// See the README.md file for an image of this keymap.
+
+#include QMK_KEYBOARD_H
+#include "keymap_bepo.h"
+
+// The layers that we are defining for this keyboards.
+#define BASE 0
+#define FN 1
+#define MOUSE 2
+#define NUMS 3
+#define SWAP 4
+#define SYSLEDS 5
+
+// The Tap Dance identifiers, used in the TD keycode and tap_dance_actions array.
+#define TAP_MACRO 0
+
+// A 'transparent' key code (that falls back to the layers below it).
+#define ___ KC_TRANSPARENT
+
+// A 'blocking' key code. Does nothing but prevent falling back to another layer.
+#define XXX KC_NO
+
+// Some combined keys (one normal keycode when tapped and one modifier or layer
+// toggle when held).
+#define ESC_FN    LT(FN, KC_ESC)        // ESC key and FN layer toggle.
+#define M_RSFT    MT(MOD_RSFT, BP_M)    // 'M' key and right shift modifier.
+#define W_RCTL    MT(MOD_RCTL, BP_W)    // 'W' key and right control modifier.
+#define SPC_RALT  MT(MOD_RALT, KC_SPC)  // SPACE key and right alt modifier.
+#define PERC_FN    LT(FN, BP_PERC)      // '%' key and FN layer toggle.
+
+// The most portable copy/paste keys (windows (mostly), linux, and some terminal emulators).
+#define MK_CUT    LSFT(KC_DEL)  // shift + delete
+#define MK_COPY   LCTL(KC_INS)  // ctrl + insert
+#define MK_PASTE  LSFT(KC_INS)  // shift + insert
+
+// Custom keycodes
+enum {
+  // SAFE_RANGE must be used to tag the first element of the enum.
+  // DYNAMIC_MACRO_RANGE must always be the last element of the enum if other
+  // values are added (as its value is used to create a couple of other keycodes
+  // after it).
+  DYNAMIC_MACRO_RANGE = SAFE_RANGE,
+};
+
+// This file must be included after DYNAMIC_MACRO_RANGE is defined...
+#include "dynamic_macro.h"
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+  // Layer 0: basic keys.
+  [BASE] = KEYMAP(  
+    /* left hand */
+    BP_DLR,   BP_DQOT, BP_LGIL, BP_RGIL, BP_LPRN, BP_RPRN, KC_DEL,
+    KC_TAB,   BP_B,    BP_ECUT, BP_P,    BP_O,    BP_EGRV, KC_BSPC,
+    KC_LSFT,  BP_A,    BP_U,    BP_I,    BP_E,    BP_COMM,
+    KC_LCTRL, BP_AGRV, BP_Y,    BP_X,    BP_DOT,  BP_K,    KC_ENT,
+    ESC_FN,   BP_ECRC, KC_LGUI, KC_LALT, SPC_RALT,
+                                                          TT(SWAP), KC_MNXT,
+                                                                    KC_MPLY,
+                                                  TT(FN), TT(NUMS), KC_MPRV,
+    /* right hand */
+        KC_DEL,  BP_AT,   BP_PLUS,  BP_MINS, BP_SLSH,     BP_ASTR, BP_EQL,
+        KC_BSPC, BP_DCRC, BP_V,     BP_D,    BP_L,        BP_J,    BP_Z,
+                 BP_C,    BP_T,     BP_S,    BP_R,        BP_N,    M_RSFT,
+        KC_ENT,  BP_APOS, BP_Q,     BP_G,    BP_H,        BP_F,    W_RCTL,
+                          SPC_RALT, KC_LALT, TT(SYSLEDS), BP_CCED, PERC_FN,
+    KC_LEFT, KC_RIGHT,
+    KC_UP,
+    KC_DOWN, TD(TAP_MACRO), TT(MOUSE)),
+
+  // Layer 1: function and media keys.
+  [FN] = KEYMAP(  
+    /* left hand */
+    KC_SLEP, KC_F1, KC_F2,  KC_F3,   KC_F4,    KC_F5,    ___,
+    ___,     ___,   ___,    ___,     ___,      ___,      ___,
+    ___,     ___,   ___,    ___,     ___,      KC_LSFT,
+    ___,     ___,   MK_CUT, MK_COPY, MK_PASTE, KC_LCTRL, ___,
+    ___,     ___,   ___,    ___,     ___,
+                                                     ___, KC_VOLU,
+                                                          KC_VOLD,
+                                             ___,    ___, KC_MUTE,
+    /* right hand */
+        ___, KC_F6, KC_F7,   KC_F8,   KC_F9,    KC_F10,  KC_F11,
+        ___, ___,   KC_HOME, KC_UP,   KC_END,   KC_PGUP, KC_F12,
+             ___,   KC_LEFT, KC_DOWN, KC_RIGHT, KC_PGDN, ___,
+        ___, ___,   ___,     ___,     ___,      ___,     ___,
+                    ___,     ___,     ___,      ___,     ___,
+    KC_HOME, KC_END,
+    KC_PGUP,
+    KC_PGDN, ___,    ___),
+    // Note that any change to the FN layer above must be added to
+    // the MOUSE layer below (except for the arrow keys).
+
+  // Layer 2: Mouse control.
+  [MOUSE] = KEYMAP(  
+    /* left hand */
+    KC_SLEP, KC_F1, KC_F2,   KC_F3,   KC_F4,    KC_F5,    ___,
+    ___,     ___,   KC_BTN4, KC_MS_U, KC_BTN5,  ___,      ___,
+    ___,     ___,   KC_MS_L, KC_MS_D, KC_MS_R,  KC_LSFT,
+    ___,     ___,   MK_CUT,  MK_COPY, MK_PASTE, KC_LCTRL, ___,
+    ___,     ___,   ___,     ___,     ___,
+                                                  ___, KC_VOLU,
+                                                       KC_VOLD,
+                                             ___, ___, KC_MUTE,
+    /* right hand */
+         ___, KC_F6, KC_F7,   KC_F8,   KC_F9,   KC_F10, KC_F11,
+         ___, ___,   XXX,     KC_WH_U, XXX,     XXX,    KC_F12,
+              ___,   KC_WH_L, KC_WH_D, KC_WH_R, XXX,    ___,
+         ___, ___,   KC_ACL0, KC_ACL1, KC_ACL2, ___,    ___,
+                     KC_BTN1, KC_BTN2, KC_BTN3, ___,    ___,
+    ___, ___,
+    ___,
+    ___, ___, ___),
+
+  // Layer 3: Numeric keypad and system keys.
+  [NUMS] = KEYMAP(  
+    /* left hand */
+    KC_PSCR, KC_INS, KC_PAUS,    ___,     ___,      ___, ___,
+    ___,     ___,    ___,        ___,     ___,      ___, ___,
+    ___,     ___,    ___,        ___,     ___,      ___,
+    ___,     ___,    MK_CUT,     MK_COPY, MK_PASTE, ___, ___,
+    ___,     ___,    ___,        ___,     ___,
+                                              ___, ___,
+                                                   ___,
+                                         ___, ___, ___,
+    /* right hand */
+         ___,     ___,     ___,   ___,   ___,     ___,     KC_NLCK,
+         ___,     KC_PEQL, KC_P7, KC_P8, KC_P9,   KC_PMNS, KC_SLCK,
+                  KC_PCMM, KC_P4, KC_P5, KC_P6,   KC_PPLS, ___,
+         KC_PENT, KC_P0,   KC_P1, KC_P2, KC_P3,   KC_PAST, ___,
+                           ___,   ___,   ___,     KC_PSLS, ___,
+    ___, ___,
+    ___,
+    ___, ___, ___),
+
+  // Layer 4: hand swap, all keys are mirrored to the other side of the keyboard
+  // except for the layer toggle itself (so there is no right arrow when this
+  // layer is activated).
+  [SWAP] = KEYMAP(  
+    /* left hand */
+    ___, ___, ___, ___, ___, ___, ___,
+    ___, ___, ___, ___, ___, ___, ___,
+    ___, ___, ___, ___, ___, ___,
+    ___, ___, ___, ___, ___, ___, ___,
+    ___, ___, ___, ___, ___,
+                             TT(SWAP), ___,
+                                       ___,
+                             ___, ___, ___,
+    /* right hand */
+         ___, ___, ___, ___, ___, ___, ___,
+         ___, ___, ___, ___, ___, ___, ___,
+              ___, ___, ___, ___, ___, ___,
+         ___, ___, ___, ___, ___, ___, ___,
+                   ___, ___, ___, ___, ___,
+    ___, TT(SWAP),
+    ___,
+    ___, ___,      ___),
+  // Layer 5: The LEDs are showing the "standard" caps/num/scroll lock indicator
+  // instead of their default which shows the currently active layers (FN, NUMS,
+  // and MOUSE in that order).
+  [SYSLEDS] = KEYMAP(  
+    /* left hand */
+    ___, ___, ___, ___, ___, ___, ___,
+    ___, ___, ___, ___, ___, ___, ___,
+    ___, ___, ___, ___, ___, ___,
+    ___, ___, ___, ___, ___, ___, ___,
+    ___, ___, ___, ___, ___,
+                                  ___, ___,
+                                       ___,
+                             ___, ___, ___,
+    /* right hand */
+         ___, ___, ___, ___, ___,         ___, ___,
+         ___, ___, ___, ___, ___,         ___, ___,
+              ___, ___, ___, ___,         ___, ___,
+         ___, ___, ___, ___, ___,         ___, ___,
+                   ___, ___, TT(SYSLEDS), ___, ___,
+    ___, ___,
+    ___,
+    ___, ___, ___),
+};
+
+// Whether the macro 1 is currently being recorded.
+static bool is_macro1_recording = false;
+
+// The current set of active layers (as a bitmask).
+// There is a global 'layer_state' variable but it is set after the call
+// to layer_state_set_user().
+static uint32_t current_layer_state = 0;
+uint32_t layer_state_set_user(uint32_t state);
+
+// Method called at the end of the tap dance on the TAP_MACRO key. That key is
+// used to start recording a macro (double tap or more), to stop recording (any
+// number of tap), or to play the recorded macro (1 tap).
+void macro_tapdance_fn(qk_tap_dance_state_t *state, void *user_data) {
+  uint16_t keycode;
+  keyrecord_t record;
+  dprintf("macro_tap_dance_fn %d\n", state->count);
+  if (is_macro1_recording) {
+    keycode = DYN_REC_STOP;
+    is_macro1_recording = false;
+    layer_state_set_user(current_layer_state);
+  } else if (state->count == 1) {
+    keycode = DYN_MACRO_PLAY1;
+  } else {
+    keycode = DYN_REC_START1;
+    is_macro1_recording = true;
+    layer_state_set_user(current_layer_state);
+  }
+
+  record.event.pressed = true;
+  process_record_dynamic_macro(keycode, &record);
+  record.event.pressed = false;
+  process_record_dynamic_macro(keycode, &record);
+}
+
+// The definition of the tap dance actions:
+qk_tap_dance_action_t tap_dance_actions[] = {
+  // This Tap dance plays the macro 1 on TAP and records it on double tap.
+  [TAP_MACRO] = ACTION_TAP_DANCE_FN(macro_tapdance_fn),
+};
+
+// Runs for each key down or up event.
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+  if (keycode != TD(TAP_MACRO)) {
+    // That key is processed by the macro_tapdance_fn. Not ignoring it here is
+    // mostly a no-op except that it is recorded in the macros (and uses space).
+    // We can't just return false when the key is a tap dance, because
+    // process_record_user, is called before the tap dance processing (and
+    // returning false would eat the tap dance).
+    if (!process_record_dynamic_macro(keycode, record)) {
+      return false;
+    }
+  }
+
+  return true; // Let QMK send the enter press/release events
+}
+
+// Runs just one time when the keyboard initializes.
+void matrix_init_user(void) {
+  ergodox_right_led_1_off();
+  ergodox_right_led_2_off();
+  ergodox_right_led_3_off();
+};
+
+// Runs constantly in the background, in a loop.
+void matrix_scan_user(void) {
+
+};
+
+// The state of the LEDs requested by the system, as a bitmask.
+static uint8_t sys_led_state = 0;
+
+// Use these masks to read the system LEDs state.
+static const uint8_t sys_led_mask_num_lock = 1 << USB_LED_NUM_LOCK;
+static const uint8_t sys_led_mask_caps_lock = 1 << USB_LED_CAPS_LOCK;
+static const uint8_t sys_led_mask_scroll_lock = 1 << USB_LED_SCROLL_LOCK;
+
+// Value to use to switch LEDs on. The default value of 255 is far too bright.
+static const uint8_t max_led_value = 20;
+
+// Whether the given layer (one of the constant defined at the top) is active.
+#define LAYER_ON(layer) (current_layer_state & (1<<layer))
+
+void led_1_on(void) {
+  ergodox_right_led_1_on();
+  ergodox_right_led_1_set(max_led_value);
+}
+
+void led_2_on(void) {
+  ergodox_right_led_2_on();
+  ergodox_right_led_2_set(max_led_value);
+}
+
+void led_3_on(void) {
+  ergodox_right_led_3_on();
+  ergodox_right_led_3_set(max_led_value);
+}
+
+void led_1_off(void) {
+  ergodox_right_led_1_off();
+}
+
+void led_2_off(void) {
+  ergodox_right_led_2_off();
+}
+
+void led_3_off(void) {
+  ergodox_right_led_3_off();
+}
+
+// Called when the computer wants to change the state of the keyboard LEDs.
+void led_set_user(uint8_t usb_led) {
+  sys_led_state = usb_led;
+  if (LAYER_ON(SYSLEDS)) {
+    if (sys_led_state & sys_led_mask_caps_lock) {
+      led_1_on();
+    } else {
+      led_1_off();
+    }
+    if (sys_led_state & sys_led_mask_num_lock) {
+      led_2_on();
+    } else {
+      led_2_off();
+    }
+    if (sys_led_state & sys_led_mask_scroll_lock) {
+      led_3_on();
+    } else {
+      led_3_off();
+    }
+  }
+}
+
+uint32_t layer_state_set_user(uint32_t state) {
+  current_layer_state = state;
+  swap_hands = LAYER_ON(SWAP);
+
+  if (is_macro1_recording) {
+    led_1_on();
+    led_2_on();
+    led_3_on();
+    return state;
+  }
+
+  if (LAYER_ON(SYSLEDS)) {
+    led_set_user(sys_led_state);
+    return state;
+  }
+
+  if (LAYER_ON(FN)) {
+    led_1_on();
+  } else {
+    led_1_off();
+  }
+
+  if (LAYER_ON(NUMS)) {
+    led_2_on();
+  } else {
+    led_2_off();
+  }
+
+  if (LAYER_ON(MOUSE)) {
+    led_3_on();
+  } else {
+    led_3_off();
+  }
+
+  return state;
+};
diff --git a/keyboards/ergodox_ez/keymaps/bepo_tm_style/readme.md b/keyboards/ergodox_ez/keymaps/bepo_tm_style/readme.md
new file mode 100755 (executable)
index 0000000..d24e66c
--- /dev/null
@@ -0,0 +1,22 @@
+# Bépo compatible keymap for the Ergodox EZ, *TypeMatrix* style.
+
+This keymap is meant to be used with a [Bépo](http://bepo.fr) layout. It is
+designed to be somewhat similar to a TypeMatrix keyboard so that switching
+between one and the other is easy.
+
+![The Keymap](https://i.imgur.com/yChIbaK.png)
+
+## Build instruction
+
+To build this on Windows, under Cygwin, provided that you have installed the
+Arduino environment and Teensy loaded in the default path, you can do:
+
+```shell
+PATH=/cygdrive/c/Program\ Files\ \(x86\)/Arduino/hardware/tools/avr/bin:$PATH
+make ergodox_ez:bepo_tm_style:all
+```
+
+## Debug
+
+See https://github.com/tmk/tmk_keyboard#magic-commands for command that can help
+debug, together with the hid_listen tool (https://docs.qmk.fm/faq_debug.html).
\ No newline at end of file
diff --git a/keyboards/ergodox_ez/keymaps/bepo_tm_style/rules.mk b/keyboards/ergodox_ez/keymaps/bepo_tm_style/rules.mk
new file mode 100755 (executable)
index 0000000..6ed55e7
--- /dev/null
@@ -0,0 +1,15 @@
+MOUSEKEY_ENABLE  = yes # Mouse keys
+EXTRAKEY_ENABLE  = yes # Audio control and System control
+COMMAND_ENABLE   = yes # Commands for debug and configuration
+NKRO_ENABLE      = yes # USB Nkey Rollover - for issues, see github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
+ONEHAND_ENABLE   = yes # Allow swapping hands of keyboard
+KEY_LOCK_ENABLE  = yes # Enable the KC_LOCK key
+TAP_DANCE_ENABLE = yes # Enable the tap dance feature.
+CONSOLE_ENABLE   = yes  # Console for debug
+
+BOOTMAGIC_ENABLE = no  # Virtual DIP switch configuration
+UNICODE_ENABLE   = no
+SLEEP_LED_ENABLE = no
+API_SYSEX_ENABLE = no
+RGBLIGHT_ENABLE = no
+RGBLIGHT_ANIMATION = no