]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/mitosis/keymaps/datagrok/keymap.c
[Keyboard] Add QMK configurator JSON for Alice PCB (#6397)
[qmk_firmware.git] / keyboards / mitosis / keymaps / datagrok / keymap.c
1 #include QMK_KEYBOARD_H
2
3 #ifdef AUDIO_ENABLE
4 #include "audio.h"
5 #ifdef DEFAULT_LAYER_SONGS
6 extern float default_layer_songs[][16][2];
7 #endif
8 #endif
9
10 enum mitosis_layers
11   {
12     _xQ, // qwerty
13     _xC, // colemak
14     _xD, // dvorak
15     _xW, // workman
16     _xS, // symbols
17     _xN, // numbers
18     _xF  // functions
19   };
20
21 enum mitosis_keycodes
22   {
23     KC_LAYO = SAFE_RANGE
24   };
25
26 // Setting MITOSIS_DATAGROK_BOTTOMSPACE in rules.mk will swap the upper and
27 // lower center four thumb-keys. See keymaps/datagrok/rules.mk.
28 #ifdef MITOSIS_DATAGROK_BOTTOMSPACE
29 #undef LAYOUT
30 #define LAYOUT LAYOUT_bottomspace
31 #endif
32
33 // I don't use Japanese myself, but I've placed henkan 変換 and muhenkan 無変換
34 // in my layout to act as left and right HYPER
35
36 // Momentary tri-state layers. Mitosis default keymap does this too but employs
37 // new keymappings and a bunch of conditional code. This simpler keymap
38 // accomplishes it but with a small quirk: triggering both layers then releasing
39 // one out-of-order will leave the tri-state triggered until the other is
40 // released. Which doesn't bother me.
41
42 // The weird /*,*/ comments are a hack to get slightly better automatic
43 // tabulation in my editor.
44
45 // We use Space Cadet KC_RSPC to get _ on right shift. See config.h for details.
46
47 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
48   [_xQ] = LAYOUT(
49       KC_Q,    KC_W,       KC_E,    KC_R,    KC_T,           KC_Y,    KC_U,    KC_I,    KC_O,     KC_P,
50       KC_A,    KC_S,       KC_D,    KC_F,    KC_G,           KC_H,    KC_J,    KC_K,    KC_L,     KC_SCLN,
51       KC_Z,    KC_X,       KC_C,    KC_V,    KC_B,           KC_N,    KC_M,    KC_COMM, KC_DOT,   KC_QUOT,
52       /*,      */ KC_LGUI, KC_LCTL, MO(_xS), KC_BSPC,        KC_SPC,  MO(_xS), KC_RCTL, KC_RGUI,
53       /*,      */ KC_HENK, KC_LALT, MO(_xN), LSFT_T(KC_TAB), KC_RSPC, MO(_xN), KC_RALT, KC_MHEN),
54   [_xC] = LAYOUT(
55       KC_Q,    KC_W,       KC_F,    KC_P,    KC_G,           KC_J,    KC_L,    KC_U,    KC_Y,     KC_SCLN,
56       KC_A,    KC_R,       KC_S,    KC_T,    KC_D,           KC_H,    KC_N,    KC_E,    KC_I,     KC_O,
57       KC_Z,    KC_X,       KC_C,    KC_V,    KC_B,           KC_K,    KC_M,    KC_COMM, KC_DOT,   KC_QUOT,
58       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______,
59       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______),
60   [_xD] = LAYOUT(
61       KC_QUOT, KC_COMM,    KC_DOT,  KC_P,    KC_Y,           KC_F,    KC_G,    KC_C,    KC_R,     KC_L,
62       KC_A,    KC_O,       KC_E,    KC_U,    KC_I,           KC_D,    KC_H,    KC_T,    KC_N,     KC_S,
63       KC_SCLN, KC_Q,       KC_J,    KC_K,    KC_X,           KC_B,    KC_M,    KC_W,    KC_V,     KC_Z,
64       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______,
65       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______),
66   [_xW] = LAYOUT(
67       KC_Q,    KC_D,       KC_R,    KC_W,    KC_B,           KC_J,    KC_F,    KC_U,    KC_P,     KC_SCLN,
68       KC_A,    KC_S,       KC_H,    KC_T,    KC_G,           KC_Y,    KC_N,    KC_E,    KC_O,     KC_I,
69       KC_Z,    KC_X,       KC_M,    KC_C,    KC_V,           KC_K,    KC_L,    KC_COMM, KC_DOT,   KC_QUOT,
70       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______,
71       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______),
72   [_xS] = LAYOUT(
73       KC_ESC,  KC_GRV ,    KC_UP,   KC_EQL , KC_TILD,        KC_PLUS, KC_CIRC, KC_AMPR, KC_PERC,  KC_MINS,
74       _______, KC_LEFT,    KC_DOWN, KC_RGHT, _______,        KC_PIPE, KC_AT,   KC_DLR,  KC_HASH,  KC_ENT,
75       KC_BSLS, KC_LABK,    KC_LCBR, KC_LPRN, KC_LBRC,        KC_RBRC, KC_RPRN, KC_RCBR, KC_RABK,  KC_SLSH,
76       /*,      */ _______, _______, _______, KC_DEL,         _______, _______, _______, _______,
77       /*,      */ _______, _______, TT(_xF), _______,        _______, TT(_xF), _______, _______),
78   [_xN] = LAYOUT(
79       KC_PSCR, KC_F7,      KC_F8,   KC_F9,   KC_F10,         KC_PPLS, KC_7,    KC_8,    KC_9,     KC_PMNS,
80       KC_SLCK, KC_F4,      KC_F5,   KC_F6,   KC_F11,         KC_NLCK, KC_4,    KC_5,    KC_6,     KC_PENT,
81       KC_PAUS, KC_F1,      KC_F2,   KC_F3,   KC_F12,         KC_PAST, KC_1,    KC_2,    KC_3,     KC_PSLS,
82       /*,      */ _______, _______, TT(_xF), _______,        _______, TT(_xF), KC_0,    KC_DOT,
83       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______),
84   [_xF] = LAYOUT(
85       RESET,   KC_INS,     KC_PGUP, DEBUG,   KC_VOLU,        KC_PPLS, KC_P7,   KC_P8,   KC_P9,    KC_PMNS,
86       CK_TOGG, KC_HOME,    KC_PGDN, KC_END,  KC_VOLD,        KC_NLCK, KC_P4,   KC_P5,   KC_P6,    KC_PENT,
87       KC_LAYO, KC_MPRV,    KC_MPLY, KC_MNXT, KC_MUTE,        KC_PAST, KC_P1,   KC_P2,   KC_P3,    KC_PSLS,
88       /*,      */ CK_UP,   MU_TOG,  _______, _______,        _______, _______, KC_P0,   KC_PDOT,
89       /*,      */ CK_DOWN, MU_MOD,  _______, _______,        _______, _______, _______, _______),
90 };
91 const bool defaultlayers[] = {
92   [_xQ] = true,
93   [_xC] = true,
94   [_xD] = true,
95   [_xW] = true,
96   [_xS] = false,
97   [_xN] = false,
98   [_xF] = false,
99 };
100 const size_t defaultlayers_n = sizeof(defaultlayers) / sizeof(defaultlayers[0]);
101
102 // New keycode KC_LAYO rotates between available default layers (for e.g.,
103 // selecting a base layout). Shift+KC_LAYO makes the current one persistent.
104 bool process_record_layout(uint16_t keycode, keyrecord_t *record) {
105   uint32_t default_layer;
106   uint8_t i;
107   #if defined(AUDIO_ENABLE)
108   float saved_song[][2] = SONG(COIN_SOUND);
109   #endif
110
111   if (keycode != KC_LAYO || !record->event.pressed) {
112     return true;
113   }
114
115   if (get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))) { // shift pressed
116     // save default layer. whatever the current default layer is, store that
117     eeconfig_update_default_layer(default_layer_state);
118     #if defined(AUDIO_ENABLE)
119         PLAY_SONG(saved_song);
120     #endif
121   } else {
122     // rotate default layer.
123     // find the current default layer
124     default_layer = biton32(default_layer_state);
125     // find next valid default layer
126     for (i = 1; i < defaultlayers_n; i++) {
127       if (defaultlayers[(default_layer + i) % defaultlayers_n]) {
128         break;
129       }
130     }
131     if (i == defaultlayers_n) {
132       // we fell out of the loop without finding another default layer to switch
133       // to.
134       return false;
135     }
136     default_layer = (default_layer + i) % defaultlayers_n;
137     default_layer_set(1U<<default_layer);
138     led_set(host_keyboard_leds());
139     #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
140       PLAY_SONG(default_layer_songs[default_layer]);
141     #endif
142   }
143   return false;
144 }
145
146 // This is a hack to place <question mark> on <shift-comma> and <exclamation
147 // mark> on <shift-period>, when using an operating system configured for a
148 // US/qwerty layout.
149 // cdeq = "comma dot exclamation question"
150 bool comm_shifted = false;
151 bool ques_shifted = false;
152 bool process_record_cdeq(uint16_t keycode, keyrecord_t *record) {
153   uint8_t shifted;
154   uint16_t s_keycode;
155   bool *k_shifted;
156
157   switch (keycode) {
158   case KC_COMM:
159     s_keycode = KC_SLSH;
160     k_shifted = &comm_shifted;
161     break;
162   case KC_DOT:
163     s_keycode = KC_1;
164     k_shifted = &ques_shifted;
165     break;
166   default:
167     return true;
168   }
169
170   shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
171
172   // Keydown. If shift is currently pressed, register its alternate keycode.
173   if (record->event.pressed && shifted) {
174     *k_shifted = true;
175     register_code(s_keycode);
176     return false;
177     // Keyup. If shift was pressed back when the key was pressed, unregister
178     // its alternate keycode.
179   } else if (!(record->event.pressed) && *k_shifted) {
180     *k_shifted = false;
181     unregister_code(s_keycode);
182     return false;
183     // Otherwise, behave as normal.
184   } else {
185     return true;
186   }
187 }
188
189 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
190   return \
191     process_record_cdeq(keycode, record) && \
192     process_record_layout(keycode, record);
193 }
194
195 // Set the bits of A selected by MASK to the corresponding bits of B
196 #define setbits(A, B, MASK) A = (A & (B | ~MASK)) | (B & MASK)
197
198 void led_set_user(uint8_t usb_leds) {
199   // A simple (but technically inaccurate) model of the momentary layer state:
200   // Red layer active -> indicator = red
201   // Blue layer active -> indicator = blue
202   // Purple layer active -> indicator = purple
203   // the Pro Micro tx LED displays Num Lock status.
204   //
205   // Workman layout active -> indicator = green
206   // Workman red layer -> indicator = yellow (red + green)
207   // Workman blue layer -> indicator = cyan (blue + green)
208   // Workman purple layer -> indicator = white (red + blue + green)
209
210   // Bit #            7     6     5     4     3     2     1     0
211   // layer_state: [     | _xF | _xN | _xS | _xW | _xD | _xC | _xQ ]
212   // usb_led      [     |     |     |kana |cmps |scrl |caps | num ]
213   // PORTB:       [  NC |  10 |   9 |   8 |  14 |  16 |  15 |rxled]
214   // PORTC:       [  NC |   5 |     |     |     |     |     |     ]
215   // PORTD:       [   6 |  NC |txled|   4 | tx* | rx* | grn | p29 ]
216   // PORTE:       [     |   7 |     |     |     |     |     |     ]
217   // PORTF:       [  a0 |  a1 | red | blu |     |     |  NC |  NC ]
218   //
219   // PD0 is connected to the pairing switch and p29 on the wireless module.
220   // PF0,PF1,PB7,PC7,PD6 are not broken out by the pro micro board. I don't understand why.
221   // PB1-PB6,PD4,PD5,PD6,PF6,PF7 are not connected to the Mitosis receiver
222   // board. Each may be connected to an LED by way of a resistor (4.7k to
223   // match the others) for a total of 14 additional indicators.
224
225   uint32_t portf_bits = \
226     ((layer_state|default_layer_state)&0b01100000)>>1 | \
227     ((layer_state|default_layer_state)&0b00010000)<<1 | \
228     ((layer_state|default_layer_state)&0b01000000)>>2;
229   uint32_t portd_bits = \
230     (usb_leds&0b1)<<5 | \
231     ((layer_state|default_layer_state)&0b1000)>>2;
232   // negated because for ports 0=LED on.
233   setbits(PORTF, ~portf_bits, 0b00110000);
234   setbits(PORTD, ~portd_bits, 0b00100010);
235 }
236
237 // vim: set sw=2 et: