aboutsummaryrefslogtreecommitdiffstats
path: root/keyboards
diff options
context:
space:
mode:
authorGravatar Erez Zukerman <bulk@ezuk.org>2016-09-11 20:26:23 -0400
committerGravatar GitHub <noreply@github.com>2016-09-11 20:26:23 -0400
commitfe4b379287790c45daee472c461b18fd49892da9 (patch)
tree770af5b1ad9756c75dbe3dc9b046c54a8af0010d /keyboards
parent05b4949fd26cf7441367b4dff3a6b387a23b3203 (diff)
parent21747cc3101bb535641db5a6250aa81f860ede03 (diff)
downloadqmk_firmware-fe4b379287790c45daee472c461b18fd49892da9.tar.gz
Merge pull request #746 from DidierLoiseau/bépo
Bépo with firmware remapping for software CSA layout
Diffstat (limited to 'keyboards')
-rw-r--r--keyboards/ergodox/keymaps/bepo_csa/keymap.c527
-rw-r--r--keyboards/ergodox/keymaps/bepo_csa/readme.md162
2 files changed, 689 insertions, 0 deletions
diff --git a/keyboards/ergodox/keymaps/bepo_csa/keymap.c b/keyboards/ergodox/keymaps/bepo_csa/keymap.c
new file mode 100644
index 000000000..495242adb
--- /dev/null
+++ b/keyboards/ergodox/keymaps/bepo_csa/keymap.c
@@ -0,0 +1,527 @@
+/* TypeMatrix-2030-like keymap */
+#include "ergodox.h"
+#include "debug.h"
+#include "action_layer.h"
+#include "action_util.h"
+#include "led.h"
+#include "keymap_extras/keymap_bepo.h"
+#include "keymap_extras/keymap_canadian_multilingual.h"
+
+enum layers {
+ LR_BASE, // default layer
+ LR_CSA, // BÉPO over Canadian Multilingual (CSA)
+ LR_CSA_SFT, // shifted BÉPO over CSA
+ LR_CSA_AGR, // altgr-ed BÉPO over CSA
+ LR_CSA_AGR_SFT, // altgr-shifted BÉPO over CSA
+ LR_NUMR, // numeric layer
+ LR_FN, // fn layer
+};
+
+#define IS_CA_MULT_ENABLED() (layer_state & (1 << LR_CSA))
+
+enum macros {
+ // Characters that do not exist in CSA and must be implemented based on unicode support
+ // Note: these are intentionally declared first to be used as indexes in spec_chars below
+ UC_NDSH, // –
+ UC_MDSH, // —
+ UC_ELPS, // …
+ END_UC, // indicates the last unicode character macro
+ // other macros
+ M_CSA_SFT, // toggle shift on CSA
+ M_CSA_AGR_SFT, // toggle shift on LR_CSA_AGR (goes to LR_CSA_AGR_SFT)
+ M_CSA_SFT_AGR, // toggle AltGr on LR_CSA_SFT (goes to LR_CSA_AGR_SFT)
+ // macros for characters that need to be un-shifted in LR_CA_MULT_SHIFT
+ M_1,
+ M_2,
+ M_3,
+ M_4,
+ M_5,
+ M_6,
+ M_7,
+ M_8,
+ M_9,
+ M_0,
+ M_DEGR,
+ M_SCLN,
+ M_GRV,
+ M_NBSP,
+ // macros for characters that don't have a simple key combination in LR_CA_MULT_ALTGR
+ M_CRC,
+ // other layer macros
+ M_DBL0, // double 0
+ M_FNLR, // fn layer
+ M_NMAL, // num+alt
+};
+
+#define CSA(name) M(M_CSA_##name) // calls a CSA macro
+
+const uint16_t unicode_chars[] = {
+ [UC_NDSH] = L'–',
+ [UC_MDSH] = L'—',
+ [UC_ELPS] = L'…',
+};
+
+/* shortcut for unicode character macros */
+#define MUC(name) M(UC_##name) // calls a unicode macro
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+/* Basic layer
+ *
+ * ,--------------------------------------------------. ,--------------------------------------------------.
+ * | $ | " | « | » | ( | ) | Del | | Del | @ | + | - | / | * | W |
+ * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
+ * | Tab | B | É | P | O | È |Backsp| |Backsp| ^ | V | D | L | J | Z |
+ * |--------+------+------+------+------+------|ace | |ace |------+------+------+------+------+--------|
+ * | = | A | U | I | E | , |------| |------| C | T | S | R | N | M |
+ * |--------+------+------+------+------+------|Enter | |Enter |------+------+------+------+------+--------|
+ * | LShift | À | Y | X | . | K | | | | ' | Q | G | H | F | RShift |
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * |LCtrl | fn | LGui |numAlt| LAlt | |Alt Gr| % | App | Ç | RCtrl|
+ * `----------------------------------' `----------------------------------'
+ * ,--------------. ,-------------.
+ * | Esc | num | | Left |Right |
+ * ,------+-------+------| |------+------+------.
+ * | | | PgUp | | Up | | |
+ * |Space | Home |------| |------| End |Space |
+ * | | | PgDn | | Down | | |
+ * `---------------------' `--------------------'
+ */
+// If it accepts an argument (i.e, is a function), it doesn't need KC_.
+// Otherwise, it needs KC_*
+[LR_BASE] = KEYMAP( // layer 0 : default
+ // left hand
+ BP_DLR, KC_1, KC_2, KC_3, KC_4, KC_5, KC_DELT,
+ KC_TAB, BP_B, BP_ECUT, BP_P, BP_O, BP_EGRV, KC_BSPC,
+ BP_EQL, BP_A, BP_U, BP_I, BP_E, BP_COMM,
+ KC_LSFT, BP_AGRV, BP_Y, BP_X, BP_DOT, BP_K, KC_ENT,
+ KC_LCTL, M(M_FNLR), KC_LGUI, M(M_NMAL), KC_LALT,
+
+ KC_ESC, TG(LR_NUMR),
+ KC_PGUP,
+ KC_SPC, KC_HOME, KC_PGDN,
+
+ // right hand
+ KC_DELT, KC_6, KC_7, KC_8, KC_9, KC_0, BP_W,
+ KC_BSPC, BP_DCRC, BP_V, BP_D, BP_L, BP_J, BP_Z,
+ BP_C, BP_T, BP_S, BP_R, BP_N, BP_M,
+ KC_ENT, BP_APOS, BP_Q, BP_G, BP_H, BP_F, KC_RSFT,
+ BP_ALGR, BP_PERC, KC_APP, BP_CCED, KC_RCTL,
+
+ KC_LEFT, KC_RGHT,
+ KC_UP,
+ KC_DOWN, KC_END, KC_SPC
+ ),
+/**
+ * Same as default but for use with Canadian Multilingual on OS side
+ */
+[LR_CSA] = KEYMAP(
+ // left hand
+ KC_DLR, CSA_DQOT, CSA_LGIL, CSA_RGIL, KC_LPRN, KC_RPRN, KC_TRNS,
+ KC_TRNS, KC_B, CSA_ECUT, KC_P, KC_O, CSA_EGRV, KC_TRNS,
+ KC_EQL, KC_A, KC_U, KC_I, KC_E, KC_COMM,
+ CSA(SFT), CSA_AGRV, KC_Y, KC_X, KC_DOT, KC_K, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS,
+
+ // right hand
+ KC_TRNS, KC_AT, KC_PLUS, KC_MINS, CSA_SLSH, KC_ASTR, KC_W,
+ KC_TRNS, CSA_DCRC, KC_V, KC_D, KC_L, KC_J, KC_Z,
+ KC_C, KC_T, KC_S, KC_R, KC_N, KC_M,
+ KC_TRNS, CSA_APOS, KC_Q, KC_G, KC_H, KC_F, CSA(SFT),
+ MO(LR_CSA_AGR), KC_PERC, KC_TRNS, CSA_CCED, KC_LCTL, // RCTL has a special behaviour in CSA so use LCTL
+
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS
+ ),
+/* Shifted BÉPO over Canadian Multilingual
+ *
+ * ,--------------------------------------------------. ,--------------------------------------------------.
+ * | # | 1 | 2 | 3 | 4 | 5 | | | | 6 | 7 | 8 | 9 | 0 | |
+ * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
+ * | | | | | | | | | | ! | | | | | |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | ° | | | | | ; |------| |------| | | | | | |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | | | | | : | | | | | ? | | | | | |
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * | | | | | | | | ` | | | |
+ * `----------------------------------' `-----------------------------------'
+ * ,-------------. ,-------------.
+ * | | | | | |
+ * ,------|------|------| |------+------+------.
+ * | | | | | | | |
+ * | | |------| |------| | |
+ * | | | | | | | |
+ * `--------------------' `--------------------'
+ */
+[LR_CSA_SFT] = KEYMAP(
+ // left hand
+ KC_HASH, M(M_1), M(M_2), M(M_3), M(M_4), M(M_5), KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ M(M_DEGR),KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, M(M_SCLN),
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_COLN, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ M(M_NBSP), KC_TRNS, KC_TRNS,
+
+ // right hand
+ KC_TRNS, M(M_6), M(M_7), M(M_8), M(M_9), M(M_0), KC_TRNS,
+ KC_TRNS, KC_EXLM, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, CSA_QEST, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ CSA(SFT_AGR), M(M_GRV), KC_TRNS, KC_TRNS, KC_TRNS,
+
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, M(M_NBSP)
+ ),
+/* AltGr-ed BÉPO over Canadian Multilingual
+ * "////" indicates that the key is disabled (unsupported bépo character)
+ *
+ * ,--------------------------------------------------. ,--------------------------------------------------.
+ * | – | — | < | > | [ | ] | | | | ^ | ± | //// | ÷ | × | dead ˘ |
+ * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
+ * | | | |dead '| & | œ |dead `| | | | ¡ |dead ˇ| ð | //// | ij | ////// |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | ////// | æ | ù |dead "| € | ̛’ |------| |------| © | þ | ß | ® |dead ~| dead ¯ |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | | \ | { | } | … | ~ | | | | ¿ |dead °| μ | //// |dead ˛| |
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * | | | | | | | | //// | |dead ¸| |
+ * `----------------------------------' `-----------------------------------'
+ * ,-------------. ,-------------.
+ * | | | | | |
+ * ,------|------|------| |------+------+------.
+ * | | | | | | | |
+ * | _ | |------| |------| | _ |
+ * | | | | | | | |
+ * `--------------------' `--------------------'
+ */
+[LR_CSA_AGR] = KEYMAP(
+ // left hand
+ MUC(NDSH), MUC(MDSH), CSA_LESS, CSA_GRTR, CSA_LBRC, CSA_RBRC, KC_TRNS,
+ KC_TRNS, CSA_PIPE, CSA_DACT, KC_AMPR, CSA_OE, CSA_DGRV, KC_TRNS,
+ KC_NO, CSA_AE, CSA_UGRV, CSA_DTRM, CSA_EURO, CSA_RQOT,
+ CSA(AGR_SFT), CSA_BSLS, CSA_LCBR, CSA_RCBR, MUC(ELPS), CSA_TILD, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_UNDS, CSA(AGR_SFT), KC_TRNS,
+
+ // right hand
+ KC_TRNS, M(M_CRC), CSA_PSMS, KC_NO, CSA_DVSN, CSA_TIMS, CSA_DBRV,
+ KC_TRNS, CSA_IXLM, CSA_DCAR, CSA_ETH, KC_NO, CSA_IJ, KC_NO,
+ CSA_CPRT, CSA_THRN, CSA_SRPS, CSA_RTM, CSA_DTLD, CSA_DMCR,
+ KC_TRNS, CSA_IQST, CSA_DRNG, CSA_MU, KC_NO, CSA_DOGO, CSA(AGR_SFT),
+ KC_TRNS, KC_NO, KC_TRNS, CSA_DCED, KC_TRNS,
+
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, CSA(AGR_SFT), KC_UNDS
+ ),
+/* AltGr-shifted BÉPO over Canadian Multilingual
+ * "////" indicates that the key is disabled (unsupported bépo character or unused in bépo)
+ *
+ * ,--------------------------------------------------. ,--------------------------------------------------.
+ * | ¶ | //// | “ | ” | //// | //// | | | | //// | ¬ | ¼ | ½ | ¾ | ////// |
+ * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
+ * | | ¦ | ˝ | § | Œ | ` | | | | //// | //// | Ð | //// | IJ | ////// |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | ////// | Æ | Ù |dead-˙| //// | //// |------| |------| //// | Þ | ẞ | ™ | //// | º |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | | //// | ‘ | ’ | //// | //// | | | | //// | //// | //// | //// | ª | |
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * | | | | | | | | | | | |
+ * `----------------------------------' `----------------------------------'
+ * ,-------------. ,-------------.
+ * | | | | | |
+ * ,------|------|------| |------+------+------.
+ * | | | | | | | |
+ * | | |------| |------| | |
+ * | | | | | | | |
+ * `--------------------' `--------------------'
+ */
+[LR_CSA_AGR_SFT] = KEYMAP(
+ // left hand
+ CSA_PARG, KC_NO, CSA_LDQT, CSA_RDQT, KC_NO, KC_NO, KC_TRNS,
+ KC_TRNS, CSA_BPIP, CSA_DDCT, CSA_SECT, S(CSA_OE), M(M_GRV), KC_TRNS,
+ KC_NO, S(CSA_AE), S(CSA_UGRV), CSA_DDTA, KC_NO, KC_NO,
+ CSA(AGR_SFT), KC_NO, CSA_LQOT, CSA_RQOT, KC_NO, KC_NO, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, CSA(AGR_SFT), KC_TRNS,
+
+ // right hand
+ KC_TRNS, KC_NO, CSA_NEGT, CSA_1QRT, CSA_1HLF, CSA_3QRT, KC_NO,
+ KC_TRNS, KC_NO, KC_NO, S(CSA_ETH), KC_NO, S(CSA_IJ), KC_NO,
+ KC_NO, S(CSA_THRN), S(CSA_SRPS), CSA_TM, KC_NO, CSA_ORDO,
+ KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, CSA_ORDA, CSA(AGR_SFT),
+ CSA(SFT_AGR), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, CSA(AGR_SFT), KC_TRNS
+ ),
+/* Numeric Layer
+ *
+ * ,--------------------------------------------------. ,--------------------------------------------------.
+ * | | F1 | F2 | F3 | F4 | F5 | | | | | | Tab | / | * | - |
+ * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
+ * | | F6 | F7 | F8 | F9 | F10 | | | | | Home | 7 | 8 | 9 | + |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | | F11 | F12 | | | |------| |------| Up | End | 4 | 5 | 6 | + |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | | | | | | | | | Left | Down | Right| 1 | 2 | 3 |KpEnter |
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * | | | | | | | | 0 | 00 | . |Etr/Ctl|
+ * `----------------------------------' `-----------------------------------'
+ * ,-------------. ,-------------.
+ * | | | |n.lock|c.lock|
+ * ,------|------|------| |------+------+------.
+ * | | | | | | | |
+ * | | |------| |------| | |
+ * | | | | | | | |
+ * `--------------------' `--------------------'
+ */
+// SYMBOLS
+[LR_NUMR] = KEYMAP(
+ // left hand
+ KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
+ KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS,
+ KC_TRNS, KC_F11, KC_F12, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+
+ KC_TRNS,KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS,KC_TRNS,
+
+ // right hand
+ KC_TRNS, KC_F6, KC_F7, KC_TAB, KC_PSLS, KC_PAST, KC_PMNS,
+ KC_TRNS, KC_TRNS, KC_HOME, KC_P7, KC_P8, KC_P9, KC_PPLS,
+ KC_UP, KC_END, KC_P4, KC_P5, KC_P6, KC_PPLS,
+ KC_LEFT, KC_DOWN, KC_RGHT, KC_P1, KC_P2, KC_P3, KC_PENT,
+ KC_TRNS, KC_P0, M(M_DBL0),KC_PDOT, CTL_T(KC_PENT),
+
+ KC_NLCK, KC_CAPS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS
+),
+/* fn layer
+ *
+ * ,--------------------------------------------------. ,--------------------------------------------------.
+ * |~CA-mult| | | | | |Insert| |Insert|Eject |Power |Sleep | Wake |PrtScr|ScrollLk|
+ * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
+ * | | | | | | |VolUp | | | | | | | | Pause |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | RESET | | | Calc | Mail |Browsr|------| |------| | | | | | |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | | App | cut | copy |paste | Mute |VolDn | | | | | | | | |
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * | | | | | | | | | | | |
+ * `----------------------------------' `----------------------------------'
+ * ,-------------. ,-------------.
+ * | | | | | |
+ * ,------|------|------| |------+------+------.
+ * | | | Next | | | | |
+ * | Mute | play |------| |------| | |
+ * | | | Prev | | | | |
+ * `--------------------' `--------------------'
+ */
+// MEDIA AND MOUSE
+[LR_FN] = KEYMAP(
+ TG(LR_CSA), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_INS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU,
+ RESET, KC_TRNS, KC_TRNS, KC_CALC, KC_MAIL, KC_WHOM,
+ KC_TRNS, KC_APP, S(KC_DELT), LCTL(KC_INS),S(KC_INS), KC_MUTE, KC_VOLD,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+
+ KC_TRNS, KC_TRNS,
+ KC_MPRV,
+ KC_MUTE, KC_MPLY, KC_MNXT,
+
+ // right hand
+ KC_INS, KC_EJCT, KC_PWR, KC_SLEP, KC_WAKE, KC_PSCR, KC_SLCK,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PAUS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS
+),
+};
+
+const uint16_t PROGMEM fn_actions[] = {
+};
+
+void hold_shift(void) {
+ register_code(KC_LSHIFT);
+}
+
+void release_shift(void) {
+ unregister_code(KC_LSHIFT);
+}
+
+uint16_t hextokeycode(int hex) {
+ if (hex == 0x0) {
+ return KC_P0;
+ } else if (hex < 0xA) {
+ return KC_P1 + (hex - 0x1);
+ } else {
+ return KC_A + (hex - 0xA);
+ }
+}
+
+void send_unicode(uint16_t unicode)
+{
+ // For more info on how this works per OS, see here: https://en.wikipedia.org/wiki/Unicode_input#Hexadecimal_code_input
+ // Implemented for Windows:
+ // Pressing ALT followed by + followed by the unicode code point in hex.
+ // Requires registry key HKEY_CURRENT_USER\Control Panel\Input Method\EnableHexNumpad set to String 1
+ register_code(KC_LALT);
+ register_code(KC_PPLS);
+ unregister_code(KC_PPLS);
+
+ for (int i = 12; i >= 0; i -= 4) {
+ register_code(hextokeycode((unicode >> i) & 0xF));
+ unregister_code(hextokeycode((unicode >> i) & 0xF));
+ }
+
+ unregister_code(KC_LALT);
+}
+
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+ // MACRODOWN only works in this function
+ switch(id) {
+ case 0 ... END_UC:
+ if (record->event.pressed) {
+ send_unicode(unicode_chars[id]);
+ }
+ break;
+ case M_CSA_SFT:
+ // BÉPO over CSA: toggle shift layer
+ layer_invert(LR_CSA_SFT);
+ if (record->event.pressed) {
+ hold_shift();
+ } else {
+ release_shift();
+ }
+ break;
+ case M_CSA_SFT_AGR:
+ // BÉPO over CSA: from shift layer, momentary altgr+shift layer
+ layer_invert(LR_CSA_AGR);
+ layer_invert(LR_CSA_AGR_SFT);
+ if (record->event.pressed) {
+ // shift not needed for LR_CSA_AGR_SFT
+ release_shift();
+ } else {
+ // back to shift layer
+ hold_shift();
+ }
+ break;
+ case M_CSA_AGR_SFT:
+ // BÉPO over CSA: from altgr layer, momentary altgr+shift layer
+ layer_invert(LR_CSA_SFT);
+ layer_invert(LR_CSA_AGR_SFT);
+ break;
+ case M_1 ... M_0:
+ case M_DEGR:
+ case M_SCLN:
+ case M_GRV:
+ case M_NBSP:
+ // macros of the shift layer that require to release shift
+ if (record->event.pressed) {
+ release_shift();
+ switch (id) {
+ case M_1 ... M_0:
+ register_code(KC_1 + (id - M_1));
+ break;
+ case M_DEGR:
+ return MACRO(DOWN(CSA_ALTGR), D(SCLN), END);
+ case M_SCLN:
+ return MACRO(D(SCLN), END);
+ case M_GRV:
+ return MACRO(I(75), DOWN(CSA_ALTGR), TYPE(CSA_DCRC), UP(CSA_ALTGR), T(SPACE), END);
+ case M_NBSP:
+ // use weak mod such that pressing another key will not be affected
+ add_weak_mods(MOD_BIT(CSA_ALTGR));
+ return MACRO(D(SPACE), END);
+ }
+ } else {
+ hold_shift();
+ switch (id) {
+ case M_1 ... M_0:
+ unregister_code(KC_1 + (id - M_1));
+ break;
+ case M_DEGR:
+ return MACRO(UP(CSA_ALTGR), U(SCLN), END);
+ case M_SCLN:
+ return MACRO(U(SCLN), END);
+ case M_NBSP:
+ del_weak_mods(MOD_BIT(CSA_ALTGR));
+ return MACRO(U(SPACE), END);
+ }
+ }
+ break;
+ case M_CRC:
+ if (record->event.pressed) {
+ return MACRO(I(75), TYPE(CSA_DCRC), T(SPACE), END);
+ }
+ break;
+ case M_DBL0:
+ if (record->event.pressed) {
+ return MACRO( I(25), T(P0), T(P0), END );
+ }
+ break;
+ case M_FNLR:
+ layer_invert(LR_NUMR);
+ layer_invert(LR_FN);
+ break;
+ case M_NMAL:
+ layer_invert(LR_NUMR);
+ if (record->event.pressed) {
+ register_code(KC_LALT);
+ } else {
+ unregister_code(KC_LALT);
+ }
+ break;
+ }
+ return MACRO_NONE;
+};
+
+// Runs just one time when the keyboard initializes.
+void matrix_init_user(void) {
+};
+
+// Runs constantly in the background, in a loop.
+void matrix_scan_user(void) {
+
+ ergodox_board_led_off();
+ ergodox_right_led_1_off();
+ ergodox_right_led_2_off();
+ ergodox_right_led_3_off();
+ // led 1: numeric layer
+ if (layer_state & (1 << LR_NUMR)) {
+ ergodox_right_led_1_on();
+ }
+ // led 2: BÉPO over Canadian Multilingual
+ if (IS_CA_MULT_ENABLED()) {
+ ergodox_right_led_2_on();
+ }
+ // led 3: caps lock
+ if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) {
+ ergodox_right_led_3_on();
+ }
+};
diff --git a/keyboards/ergodox/keymaps/bepo_csa/readme.md b/keyboards/ergodox/keymaps/bepo_csa/readme.md
new file mode 100644
index 000000000..d4975b226
--- /dev/null
+++ b/keyboards/ergodox/keymaps/bepo_csa/readme.md
@@ -0,0 +1,162 @@
+# BÉPO Keymap with firmware-remapping for software CSA layout
+
+This is a keymap intended to be used with the [BÉPO layout](http://bepo.fr), a French ergonomic layout designed by following Dvorak's principles.
+
+The particularity of this keymap is that it supports using the [Canadian Multilingual Standard layout](https://en.wikipedia.org/wiki/QWERTY#Canadian_Multilingual_Standard) (also known as _ACNOR keyboard_ or _CSA keyboard_, see also the [French page](https://fr.wikipedia.org/wiki/QWERTY#Clavier_canadien_multilingue_standard) which contains more details) on the OS side, by enabling the _CSA_ layer. This is especially useful for operating systems that natively provide CSA, but not BÉPO, like Windows. The CSA layout was chosen because it is probably the standard layout that provides the best character set coverage.
+
+This keymap is based on the [tm2030](../tm2030/) keymap, whose goal was to have a [TypeMatrix™ 2030](http://typematrix.com/2030/features.php) inspired layout for the ErgoDox EZ.
+
+As this keyboard is intended for French people, the rest of this page will be in French.
+
+# Keymap BÉPO avec support en firmware pour utilisation avec la disposition CSA en software
+
+Cette keymap a été conçue pour être utilisée avec la [disposition BÉPO](http://bepo.fr), la disposition francophone, ergonomique et libre basée sure les principes de Dvorak.
+
+La particularité de cette keymap est qu'elle supporte l'utilisation du [clavier canadien multilingue standard](https://fr.wikipedia.org/wiki/QWERTY#Clavier_canadien_multilingue_standard) (aussi appelé _clavier ACNOR_ ou _clavier CSA_) du côté du système d'exploitation, en activant la couche _CSA_. Ceci s'avère particulièrement utile pour les systèmes d'exploitations qui fournissent nativement le CSA, mais pas le BÉPO, comme Windows. Le clavier CSA a été choisi comme base car c'est probablement la disposition standard qui fournit la meilleure couverture en termes de caractères disponibles.
+
+Cette keymap est basée sur la keymap [tm2030](../tm2030/), dont le but est de fournir une disposition inspirée du [TypeMatrix™ 2030](http://typematrix.com/2030/features.php) pour l'ErgoDox EZ.
+
+## Couche de base
+C'est la couche par défaut, proche du TypeMatrix, avec les différences suivantes:
+- La ligne du haut (les touches `F`) et la colonne de droite sont retirées, les touches correspondantes étant déplacées ailleurs.
+- Les touches situés en bas à gauche sont redisposées dans cet ordre: `Ctrl`, `fn`, `Gui`, `num+Alt`, `Alt`
+- Les touches `shuffle` (`Alt+Tab`) et `desktop` ne sont pas supportés
+- `W` est déplacé à la place de `=`
+- `=` est déplacé sous `Tab` (au lieu d'avoir un grand `Shift`)
+- `%` et `Ç` sont déplacés à la place de `Home` et `End` respectivement
+- Les flèches ainsi que `PgUp`/`PgDown`/`Home`/`End` sont déplacées sur les pouces
+
+À noter que pour `W` et `Ç`, le but a été de ne pas les déplacer trop par rapport à la disposition BÉPO _standard_, afin de pouvoir repasser facilement sur un TypeMatrix ou un clavier traditionnel.
+
+
+```
+,--------------------------------------------------. ,--------------------------------------------------.
+| $ | " | « | » | ( | ) | Del | | Del | @ | + | - | / | * | W |
+|--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
+| Tab | B | É | P | O | È |Backsp| |Backsp| ^ | V | D | L | J | Z |
+|--------+------+------+------+------+------|ace | |ace |------+------+------+------+------+--------|
+| = | A | U | I | E | , |------| |------| C | T | S | R | N | M |
+|--------+------+------+------+------+------|Enter | |Enter |------+------+------+------+------+--------|
+| LShift | À | Y | X | . | K | | | | ' | Q | G | H | F | RShift |
+`--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ |LCtrl | fn | LGui |numAlt| LAlt | |Alt Gr| % | App | Ç | RCtrl|
+ `----------------------------------' `----------------------------------'
+ ,--------------. ,-------------.
+ | Esc | num | | Left |Right |
+ ,------+-------+------| |------+------+------.
+ | | | PgUp | | Up | | |
+ |Space | Home |------| |------| End |Space |
+ | | | PgDn | | Down | | |
+ `---------------------' `--------------------'
+```
+
+### Changer de couche
+
+- Utilisez `num` pour activer/désactiver [la couche numérique](#couche-numérique)
+- Maintenez `fn` pour activer temporairement [les couches numériques et Fn](#couche-fn)
+- Maintenez `numAlt` pour activer temporairement la couche numérique combinée avec `Alt` (facilite l'utilisation des raccourcis tels que `Alt`+`F4`)
+
+### Diodes
+Les diodes de l'ErgoDox EZ (côté droit) sont utilisées de la façon suivante :
+
+- diode de gauche (rouge) : indique l'activation de [la couche numérique](#couche-numérique)
+- diode du milieu (verte) : indique l'activation du [mode CSA](#couche-csa)
+- diode de droite (bleue) : indique le verrouillage majuscules
+
+## Couche CSA
+La couche _CSA_ est la même que la couche de base, pour une utilisation avec un clavier Canadien Multilingue configuré dans le système d'exploitation.
+
+Pour l'activer, appuyez sur `fn`+`$`. La [diode](#diodes) verte indique que la couche CSA est activée.
+
+### Limitations
+Seuls les caractères présents dans le clavier CSA sont parfaitement supportés. De manière générale, il s'agit des caractères suivants :
+
+- toute la couche de base
+- tous les caractères accessibles en `Shift`
+- tous les caractères de la main gauche accessibles en `AltGr` à l'exception du `≠`
+- environ la moitié des caractères de la main droite accessibles en `AltGr` et la moitié des caractères accessibles en `AltGr`+`Shift` (consultez [le fichier source](keymap.c) pour voir les caractères supportés)
+
+En particulier, les caractères suivants sont émulés via le support Unicode (Windows seulement):
+
+- le tiret cadratin (tiret long) : —
+- le tiret demi-cadratin (demi tiret) : –
+- les points de suspension : …
+
+L'implémentation actuelle ne fonctionne pas dans toutes les applications, en particulier les applications MS Office.
+
+Il est probable que l'utilisation de la couche CSA ne fonctionne pas correctement dans certains jeux vidéos.
+
+Cette fonctionnalité a été conçue et testée essentiellment pour Windows (7).
+
+### Détails techniques
+Techniquement, la couche CSA est en réalité composée de 4 couches servant à émuler la couche de base, les appuis sur `Shift` ou `Alt` et la combinaison des deux.
+
+Le changement de couches se fait par des macros afin d'activer ou désactiver plusieurs couches et la touche `Shift` en même temps.
+
+Certains caractères sont également implémentés par des macros, notamment ceux de la couche `Shift` qui n'ont pas besoin de cette touche en CSA, comme les chiffres.
+
+Les caractères Unicode se basent sur une implémentation spécifique et non celle fournie dans QMK — il faudrait sans doute migrer le code. Notez la façon dont ces caractères sont déclarés tels quels dans [le code source](keymap.c) (tableau `unicode_char`).
+
+## Couche numérique
+Couche numérique proche du TM lorsqu'on active `num`, avec les différences suivantes :
+
+- Le clavier numérique est déplacés de 1 vers le haut et vers la droite.
+- Les flèches sont décalées de 1 vers la gauche.
+- Fournit l'accès aux touches `F1` à `F12`, `caps-lock` et `num-lock`.
+
+La couche numérique est indiquée par la [diode](#diodes) de gauche (rouge). Caps-lock est indiqué par la diode de droite (bleue).
+
+La touche `numAlt` de [la couche de base](#couche-de-base) permet d'activer la couche numérique et la touche `Alt` simultanément, afin de faciliter les raccourcis claviers comme `Alt`+`F4`.
+
+```
+,--------------------------------------------------. ,--------------------------------------------------.
+| | F1 | F2 | F3 | F4 | F5 | | | | | | Tab | / | * | - |
+|--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
+| | F6 | F7 | F8 | F9 | F10 | | | | | Home | 7 | 8 | 9 | + |
+|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+| | F11 | F12 | | | |------| |------| Up | End | 4 | 5 | 6 | + |
+|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+| | | | | | | | | Left | Down | Right| 1 | 2 | 3 |KpEnter |
+`--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ | | | | | | | | 0 | 00 | . |Etr/Ctl|
+ `----------------------------------' `-----------------------------------'
+ ,-------------. ,-------------.
+ | | | |n.lock|c.lock|
+ ,------|------|------| |------+------+------.
+ | | | | | | | |
+ | | |------| |------| | |
+ | | | | | | | |
+ `--------------------' `--------------------'
+```
+
+## Couche Fn
+Activée simultanément avec la couche numérique lorsque l'on maintient la touche `fn`. Comme sur le TM, elle fournit l'accès aux fonctionnalités suivantes :
+
+- `couper`, `copier` et `coller` — attention: ne pas utiliser dans l'explorateur de fichiers.
+- monter/baisser/couper le volume — seulement accessible en main gauche, contrairement au TM.
+- piste précédente/suivante
+- calculatrice, e-mail et page d'accueil du navigateur web
+- `insert`, `power`, `sleep`, `wake`, `print screen`, `scroll-lock` et `pause`
+- ~CSA: (dés)activation de [la couche CSA](#couche-csa) sur `$`
+- RESET: rechargement du firmware avec Teensy-Loader (pour les développeurs)
+
+```
+,--------------------------------------------------. ,--------------------------------------------------.
+| ~CSA | | | | | |Insert| |Insert|Eject |Power |Sleep | Wake |PrtScr|ScrollLk|
+|--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
+| | | | | | |VolUp | | | | | | | | Pause |
+|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+| RESET | | | Calc | Mail |Browsr|------| |------| | | | | | |
+|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+| | App | cut | copy |paste | Mute |VolDn | | | | | | | | |
+`--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ | | | | | | | | | | | |
+ `----------------------------------' `----------------------------------'
+ ,-------------. ,-------------.
+ | | | | | |
+ ,------|------|------| |------+------+------.
+ | | | Next | | | | |
+ | Mute | play |------| |------| | |
+ | | | Prev | | | | |
+ `--------------------' `--------------------'
+``` \ No newline at end of file