diff options
Diffstat (limited to 'tmk_core/common')
45 files changed, 266 insertions, 5131 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c deleted file mode 100644 index bd41d28b6..000000000 --- a/tmk_core/common/action.c +++ /dev/null | |||
| @@ -1,1093 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012,2013 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | #include "host.h" | ||
| 18 | #include "keycode.h" | ||
| 19 | #include "keyboard.h" | ||
| 20 | #include "mousekey.h" | ||
| 21 | #include "command.h" | ||
| 22 | #include "led.h" | ||
| 23 | #include "action_layer.h" | ||
| 24 | #include "action_tapping.h" | ||
| 25 | #include "action_macro.h" | ||
| 26 | #include "action_util.h" | ||
| 27 | #include "action.h" | ||
| 28 | #include "wait.h" | ||
| 29 | |||
| 30 | #ifdef BACKLIGHT_ENABLE | ||
| 31 | # include "backlight.h" | ||
| 32 | #endif | ||
| 33 | |||
| 34 | #ifdef DEBUG_ACTION | ||
| 35 | # include "debug.h" | ||
| 36 | #else | ||
| 37 | # include "nodebug.h" | ||
| 38 | #endif | ||
| 39 | |||
| 40 | #ifdef POINTING_DEVICE_ENABLE | ||
| 41 | # include "pointing_device.h" | ||
| 42 | #endif | ||
| 43 | |||
| 44 | int tp_buttons; | ||
| 45 | |||
| 46 | #if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) | ||
| 47 | int retro_tapping_counter = 0; | ||
| 48 | #endif | ||
| 49 | |||
| 50 | #ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY | ||
| 51 | __attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { return false; } | ||
| 52 | #endif | ||
| 53 | |||
| 54 | #ifdef RETRO_TAPPING_PER_KEY | ||
| 55 | __attribute__((weak)) bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) { return false; } | ||
| 56 | #endif | ||
| 57 | |||
| 58 | #ifndef TAP_CODE_DELAY | ||
| 59 | # define TAP_CODE_DELAY 0 | ||
| 60 | #endif | ||
| 61 | #ifndef TAP_HOLD_CAPS_DELAY | ||
| 62 | # define TAP_HOLD_CAPS_DELAY 80 | ||
| 63 | #endif | ||
| 64 | /** \brief Called to execute an action. | ||
| 65 | * | ||
| 66 | * FIXME: Needs documentation. | ||
| 67 | */ | ||
| 68 | void action_exec(keyevent_t event) { | ||
| 69 | if (!IS_NOEVENT(event)) { | ||
| 70 | dprint("\n---- action_exec: start -----\n"); | ||
| 71 | dprint("EVENT: "); | ||
| 72 | debug_event(event); | ||
| 73 | dprintln(); | ||
| 74 | #if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) | ||
| 75 | retro_tapping_counter++; | ||
| 76 | #endif | ||
| 77 | } | ||
| 78 | |||
| 79 | if (event.pressed) { | ||
| 80 | // clear the potential weak mods left by previously pressed keys | ||
| 81 | clear_weak_mods(); | ||
| 82 | } | ||
| 83 | |||
| 84 | #ifdef SWAP_HANDS_ENABLE | ||
| 85 | if (!IS_NOEVENT(event)) { | ||
| 86 | process_hand_swap(&event); | ||
| 87 | } | ||
| 88 | #endif | ||
| 89 | |||
| 90 | keyrecord_t record = {.event = event}; | ||
| 91 | |||
| 92 | #ifndef NO_ACTION_ONESHOT | ||
| 93 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 94 | if (has_oneshot_layer_timed_out()) { | ||
| 95 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); | ||
| 96 | } | ||
| 97 | if (has_oneshot_mods_timed_out()) { | ||
| 98 | clear_oneshot_mods(); | ||
| 99 | } | ||
| 100 | # ifdef SWAP_HANDS_ENABLE | ||
| 101 | if (has_oneshot_swaphands_timed_out()) { | ||
| 102 | clear_oneshot_swaphands(); | ||
| 103 | } | ||
| 104 | # endif | ||
| 105 | # endif | ||
| 106 | #endif | ||
| 107 | |||
| 108 | #ifndef NO_ACTION_TAPPING | ||
| 109 | action_tapping_process(record); | ||
| 110 | #else | ||
| 111 | process_record(&record); | ||
| 112 | if (!IS_NOEVENT(record.event)) { | ||
| 113 | dprint("processed: "); | ||
| 114 | debug_record(record); | ||
| 115 | dprintln(); | ||
| 116 | } | ||
| 117 | #endif | ||
| 118 | } | ||
| 119 | |||
| 120 | #ifdef SWAP_HANDS_ENABLE | ||
| 121 | bool swap_hands = false; | ||
| 122 | bool swap_held = false; | ||
| 123 | |||
| 124 | /** \brief Process Hand Swap | ||
| 125 | * | ||
| 126 | * FIXME: Needs documentation. | ||
| 127 | */ | ||
| 128 | void process_hand_swap(keyevent_t *event) { | ||
| 129 | static swap_state_row_t swap_state[MATRIX_ROWS]; | ||
| 130 | |||
| 131 | keypos_t pos = event->key; | ||
| 132 | swap_state_row_t col_bit = (swap_state_row_t)1 << pos.col; | ||
| 133 | bool do_swap = event->pressed ? swap_hands : swap_state[pos.row] & (col_bit); | ||
| 134 | |||
| 135 | if (do_swap) { | ||
| 136 | event->key.row = pgm_read_byte(&hand_swap_config[pos.row][pos.col].row); | ||
| 137 | event->key.col = pgm_read_byte(&hand_swap_config[pos.row][pos.col].col); | ||
| 138 | swap_state[pos.row] |= col_bit; | ||
| 139 | } else { | ||
| 140 | swap_state[pos.row] &= ~(col_bit); | ||
| 141 | } | ||
| 142 | } | ||
| 143 | #endif | ||
| 144 | |||
| 145 | #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) | ||
| 146 | bool disable_action_cache = false; | ||
| 147 | |||
| 148 | void process_record_nocache(keyrecord_t *record) { | ||
| 149 | disable_action_cache = true; | ||
| 150 | process_record(record); | ||
| 151 | disable_action_cache = false; | ||
| 152 | } | ||
| 153 | #else | ||
| 154 | void process_record_nocache(keyrecord_t *record) { process_record(record); } | ||
| 155 | #endif | ||
| 156 | |||
| 157 | __attribute__((weak)) bool process_record_quantum(keyrecord_t *record) { return true; } | ||
| 158 | |||
| 159 | __attribute__((weak)) void post_process_record_quantum(keyrecord_t *record) {} | ||
| 160 | |||
| 161 | #ifndef NO_ACTION_TAPPING | ||
| 162 | /** \brief Allows for handling tap-hold actions immediately instead of waiting for TAPPING_TERM or another keypress. | ||
| 163 | * | ||
| 164 | * FIXME: Needs documentation. | ||
| 165 | */ | ||
| 166 | void process_record_tap_hint(keyrecord_t *record) { | ||
| 167 | action_t action = layer_switch_get_action(record->event.key); | ||
| 168 | |||
| 169 | switch (action.kind.id) { | ||
| 170 | # ifdef SWAP_HANDS_ENABLE | ||
| 171 | case ACT_SWAP_HANDS: | ||
| 172 | switch (action.swap.code) { | ||
| 173 | case OP_SH_ONESHOT: | ||
| 174 | break; | ||
| 175 | case OP_SH_TAP_TOGGLE: | ||
| 176 | default: | ||
| 177 | swap_hands = !swap_hands; | ||
| 178 | swap_held = true; | ||
| 179 | } | ||
| 180 | break; | ||
| 181 | # endif | ||
| 182 | } | ||
| 183 | } | ||
| 184 | #endif | ||
| 185 | |||
| 186 | /** \brief Take a key event (key press or key release) and processes it. | ||
| 187 | * | ||
| 188 | * FIXME: Needs documentation. | ||
| 189 | */ | ||
| 190 | void process_record(keyrecord_t *record) { | ||
| 191 | if (IS_NOEVENT(record->event)) { | ||
| 192 | return; | ||
| 193 | } | ||
| 194 | |||
| 195 | if (!process_record_quantum(record)) { | ||
| 196 | #ifndef NO_ACTION_ONESHOT | ||
| 197 | if (is_oneshot_layer_active() && record->event.pressed) { | ||
| 198 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); | ||
| 199 | } | ||
| 200 | #endif | ||
| 201 | return; | ||
| 202 | } | ||
| 203 | |||
| 204 | process_record_handler(record); | ||
| 205 | post_process_record_quantum(record); | ||
| 206 | } | ||
| 207 | |||
| 208 | void process_record_handler(keyrecord_t *record) { | ||
| 209 | action_t action = store_or_get_action(record->event.pressed, record->event.key); | ||
| 210 | dprint("ACTION: "); | ||
| 211 | debug_action(action); | ||
| 212 | #ifndef NO_ACTION_LAYER | ||
| 213 | dprint(" layer_state: "); | ||
| 214 | layer_debug(); | ||
| 215 | dprint(" default_layer_state: "); | ||
| 216 | default_layer_debug(); | ||
| 217 | #endif | ||
| 218 | dprintln(); | ||
| 219 | |||
| 220 | process_action(record, action); | ||
| 221 | } | ||
| 222 | |||
| 223 | #if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE) | ||
| 224 | void register_button(bool pressed, enum mouse_buttons button) { | ||
| 225 | # ifdef PS2_MOUSE_ENABLE | ||
| 226 | tp_buttons = pressed ? tp_buttons | button : tp_buttons & ~button; | ||
| 227 | # endif | ||
| 228 | # ifdef POINTING_DEVICE_ENABLE | ||
| 229 | report_mouse_t currentReport = pointing_device_get_report(); | ||
| 230 | currentReport.buttons = pressed ? currentReport.buttons | button : currentReport.buttons & ~button; | ||
| 231 | pointing_device_set_report(currentReport); | ||
| 232 | # endif | ||
| 233 | } | ||
| 234 | #endif | ||
| 235 | |||
| 236 | /** \brief Take an action and processes it. | ||
| 237 | * | ||
| 238 | * FIXME: Needs documentation. | ||
| 239 | */ | ||
| 240 | void process_action(keyrecord_t *record, action_t action) { | ||
| 241 | keyevent_t event = record->event; | ||
| 242 | #ifndef NO_ACTION_TAPPING | ||
| 243 | uint8_t tap_count = record->tap.count; | ||
| 244 | #endif | ||
| 245 | |||
| 246 | #ifndef NO_ACTION_ONESHOT | ||
| 247 | bool do_release_oneshot = false; | ||
| 248 | // notice we only clear the one shot layer if the pressed key is not a modifier. | ||
| 249 | if (is_oneshot_layer_active() && event.pressed && (action.kind.id == ACT_USAGE || !IS_MOD(action.key.code)) | ||
| 250 | # ifdef SWAP_HANDS_ENABLE | ||
| 251 | && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT) | ||
| 252 | # endif | ||
| 253 | ) { | ||
| 254 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); | ||
| 255 | do_release_oneshot = !is_oneshot_layer_active(); | ||
| 256 | } | ||
| 257 | #endif | ||
| 258 | |||
| 259 | switch (action.kind.id) { | ||
| 260 | /* Key and Mods */ | ||
| 261 | case ACT_LMODS: | ||
| 262 | case ACT_RMODS: { | ||
| 263 | uint8_t mods = (action.kind.id == ACT_LMODS) ? action.key.mods : action.key.mods << 4; | ||
| 264 | if (event.pressed) { | ||
| 265 | if (mods) { | ||
| 266 | if (IS_MOD(action.key.code) || action.key.code == KC_NO) { | ||
| 267 | // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless. | ||
| 268 | // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT). | ||
| 269 | // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO). | ||
| 270 | add_mods(mods); | ||
| 271 | } else { | ||
| 272 | add_weak_mods(mods); | ||
| 273 | } | ||
| 274 | send_keyboard_report(); | ||
| 275 | } | ||
| 276 | register_code(action.key.code); | ||
| 277 | } else { | ||
| 278 | unregister_code(action.key.code); | ||
| 279 | if (mods) { | ||
| 280 | if (IS_MOD(action.key.code) || action.key.code == KC_NO) { | ||
| 281 | del_mods(mods); | ||
| 282 | } else { | ||
| 283 | del_weak_mods(mods); | ||
| 284 | } | ||
| 285 | send_keyboard_report(); | ||
| 286 | } | ||
| 287 | } | ||
| 288 | } break; | ||
| 289 | #ifndef NO_ACTION_TAPPING | ||
| 290 | case ACT_LMODS_TAP: | ||
| 291 | case ACT_RMODS_TAP: { | ||
| 292 | uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods : action.key.mods << 4; | ||
| 293 | switch (action.layer_tap.code) { | ||
| 294 | # ifndef NO_ACTION_ONESHOT | ||
| 295 | case MODS_ONESHOT: | ||
| 296 | // Oneshot modifier | ||
| 297 | if (event.pressed) { | ||
| 298 | if (tap_count == 0) { | ||
| 299 | dprint("MODS_TAP: Oneshot: 0\n"); | ||
| 300 | register_mods(mods | get_oneshot_mods()); | ||
| 301 | } else if (tap_count == 1) { | ||
| 302 | dprint("MODS_TAP: Oneshot: start\n"); | ||
| 303 | set_oneshot_mods(mods | get_oneshot_mods()); | ||
| 304 | # if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 | ||
| 305 | } else if (tap_count == ONESHOT_TAP_TOGGLE) { | ||
| 306 | dprint("MODS_TAP: Toggling oneshot"); | ||
| 307 | clear_oneshot_mods(); | ||
| 308 | set_oneshot_locked_mods(mods); | ||
| 309 | register_mods(mods); | ||
| 310 | # endif | ||
| 311 | } else { | ||
| 312 | register_mods(mods | get_oneshot_mods()); | ||
| 313 | } | ||
| 314 | } else { | ||
| 315 | if (tap_count == 0) { | ||
| 316 | clear_oneshot_mods(); | ||
| 317 | unregister_mods(mods); | ||
| 318 | } else if (tap_count == 1) { | ||
| 319 | // Retain Oneshot mods | ||
| 320 | # if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 | ||
| 321 | if (mods & get_mods()) { | ||
| 322 | clear_oneshot_locked_mods(); | ||
| 323 | clear_oneshot_mods(); | ||
| 324 | unregister_mods(mods); | ||
| 325 | } | ||
| 326 | } else if (tap_count == ONESHOT_TAP_TOGGLE) { | ||
| 327 | // Toggle Oneshot Layer | ||
| 328 | # endif | ||
| 329 | } else { | ||
| 330 | clear_oneshot_mods(); | ||
| 331 | unregister_mods(mods); | ||
| 332 | } | ||
| 333 | } | ||
| 334 | break; | ||
| 335 | # endif | ||
| 336 | case MODS_TAP_TOGGLE: | ||
| 337 | if (event.pressed) { | ||
| 338 | if (tap_count <= TAPPING_TOGGLE) { | ||
| 339 | register_mods(mods); | ||
| 340 | } | ||
| 341 | } else { | ||
| 342 | if (tap_count < TAPPING_TOGGLE) { | ||
| 343 | unregister_mods(mods); | ||
| 344 | } | ||
| 345 | } | ||
| 346 | break; | ||
| 347 | default: | ||
| 348 | if (event.pressed) { | ||
| 349 | if (tap_count > 0) { | ||
| 350 | # if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY) | ||
| 351 | if ( | ||
| 352 | # ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY | ||
| 353 | !get_ignore_mod_tap_interrupt(get_event_keycode(record->event, false), record) && | ||
| 354 | # endif | ||
| 355 | record->tap.interrupted) { | ||
| 356 | dprint("mods_tap: tap: cancel: add_mods\n"); | ||
| 357 | // ad hoc: set 0 to cancel tap | ||
| 358 | record->tap.count = 0; | ||
| 359 | register_mods(mods); | ||
| 360 | } else | ||
| 361 | # endif | ||
| 362 | { | ||
| 363 | dprint("MODS_TAP: Tap: register_code\n"); | ||
| 364 | register_code(action.key.code); | ||
| 365 | } | ||
| 366 | } else { | ||
| 367 | dprint("MODS_TAP: No tap: add_mods\n"); | ||
| 368 | register_mods(mods); | ||
| 369 | } | ||
| 370 | } else { | ||
| 371 | if (tap_count > 0) { | ||
| 372 | dprint("MODS_TAP: Tap: unregister_code\n"); | ||
| 373 | if (action.layer_tap.code == KC_CAPS) { | ||
| 374 | wait_ms(TAP_HOLD_CAPS_DELAY); | ||
| 375 | } else { | ||
| 376 | wait_ms(TAP_CODE_DELAY); | ||
| 377 | } | ||
| 378 | unregister_code(action.key.code); | ||
| 379 | } else { | ||
| 380 | dprint("MODS_TAP: No tap: add_mods\n"); | ||
| 381 | unregister_mods(mods); | ||
| 382 | } | ||
| 383 | } | ||
| 384 | break; | ||
| 385 | } | ||
| 386 | } break; | ||
| 387 | #endif | ||
| 388 | #ifdef EXTRAKEY_ENABLE | ||
| 389 | /* other HID usage */ | ||
| 390 | case ACT_USAGE: | ||
| 391 | switch (action.usage.page) { | ||
| 392 | case PAGE_SYSTEM: | ||
| 393 | if (event.pressed) { | ||
| 394 | host_system_send(action.usage.code); | ||
| 395 | } else { | ||
| 396 | host_system_send(0); | ||
| 397 | } | ||
| 398 | break; | ||
| 399 | case PAGE_CONSUMER: | ||
| 400 | if (event.pressed) { | ||
| 401 | host_consumer_send(action.usage.code); | ||
| 402 | } else { | ||
| 403 | host_consumer_send(0); | ||
| 404 | } | ||
| 405 | break; | ||
| 406 | } | ||
| 407 | break; | ||
| 408 | #endif | ||
| 409 | #ifdef MOUSEKEY_ENABLE | ||
| 410 | /* Mouse key */ | ||
| 411 | case ACT_MOUSEKEY: | ||
| 412 | if (event.pressed) { | ||
| 413 | mousekey_on(action.key.code); | ||
| 414 | } else { | ||
| 415 | mousekey_off(action.key.code); | ||
| 416 | } | ||
| 417 | switch (action.key.code) { | ||
| 418 | # if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE) | ||
| 419 | # ifdef POINTING_DEVICE_ENABLE | ||
| 420 | case KC_MS_BTN1 ... KC_MS_BTN8: | ||
| 421 | # else | ||
| 422 | case KC_MS_BTN1 ... KC_MS_BTN3: | ||
| 423 | # endif | ||
| 424 | register_button(event.pressed, MOUSE_BTN_MASK(action.key.code - KC_MS_BTN1)); | ||
| 425 | break; | ||
| 426 | # endif | ||
| 427 | default: | ||
| 428 | mousekey_send(); | ||
| 429 | break; | ||
| 430 | } | ||
| 431 | break; | ||
| 432 | #endif | ||
| 433 | #ifndef NO_ACTION_LAYER | ||
| 434 | case ACT_LAYER: | ||
| 435 | if (action.layer_bitop.on == 0) { | ||
| 436 | /* Default Layer Bitwise Operation */ | ||
| 437 | if (!event.pressed) { | ||
| 438 | uint8_t shift = action.layer_bitop.part * 4; | ||
| 439 | layer_state_t bits = ((layer_state_t)action.layer_bitop.bits) << shift; | ||
| 440 | layer_state_t mask = (action.layer_bitop.xbit) ? ~(((layer_state_t)0xf) << shift) : 0; | ||
| 441 | switch (action.layer_bitop.op) { | ||
| 442 | case OP_BIT_AND: | ||
| 443 | default_layer_and(bits | mask); | ||
| 444 | break; | ||
| 445 | case OP_BIT_OR: | ||
| 446 | default_layer_or(bits | mask); | ||
| 447 | break; | ||
| 448 | case OP_BIT_XOR: | ||
| 449 | default_layer_xor(bits | mask); | ||
| 450 | break; | ||
| 451 | case OP_BIT_SET: | ||
| 452 | default_layer_set(bits | mask); | ||
| 453 | break; | ||
| 454 | } | ||
| 455 | } | ||
| 456 | } else { | ||
| 457 | /* Layer Bitwise Operation */ | ||
| 458 | if (event.pressed ? (action.layer_bitop.on & ON_PRESS) : (action.layer_bitop.on & ON_RELEASE)) { | ||
| 459 | uint8_t shift = action.layer_bitop.part * 4; | ||
| 460 | layer_state_t bits = ((layer_state_t)action.layer_bitop.bits) << shift; | ||
| 461 | layer_state_t mask = (action.layer_bitop.xbit) ? ~(((layer_state_t)0xf) << shift) : 0; | ||
| 462 | switch (action.layer_bitop.op) { | ||
| 463 | case OP_BIT_AND: | ||
| 464 | layer_and(bits | mask); | ||
| 465 | break; | ||
| 466 | case OP_BIT_OR: | ||
| 467 | layer_or(bits | mask); | ||
| 468 | break; | ||
| 469 | case OP_BIT_XOR: | ||
| 470 | layer_xor(bits | mask); | ||
| 471 | break; | ||
| 472 | case OP_BIT_SET: | ||
| 473 | layer_state_set(bits | mask); | ||
| 474 | break; | ||
| 475 | } | ||
| 476 | } | ||
| 477 | } | ||
| 478 | break; | ||
| 479 | case ACT_LAYER_MODS: | ||
| 480 | if (event.pressed) { | ||
| 481 | layer_on(action.layer_mods.layer); | ||
| 482 | register_mods(action.layer_mods.mods); | ||
| 483 | } else { | ||
| 484 | unregister_mods(action.layer_mods.mods); | ||
| 485 | layer_off(action.layer_mods.layer); | ||
| 486 | } | ||
| 487 | break; | ||
| 488 | # ifndef NO_ACTION_TAPPING | ||
| 489 | case ACT_LAYER_TAP: | ||
| 490 | case ACT_LAYER_TAP_EXT: | ||
| 491 | switch (action.layer_tap.code) { | ||
| 492 | case OP_TAP_TOGGLE: | ||
| 493 | /* tap toggle */ | ||
| 494 | if (event.pressed) { | ||
| 495 | if (tap_count < TAPPING_TOGGLE) { | ||
| 496 | layer_invert(action.layer_tap.val); | ||
| 497 | } | ||
| 498 | } else { | ||
| 499 | if (tap_count <= TAPPING_TOGGLE) { | ||
| 500 | layer_invert(action.layer_tap.val); | ||
| 501 | } | ||
| 502 | } | ||
| 503 | break; | ||
| 504 | case OP_ON_OFF: | ||
| 505 | event.pressed ? layer_on(action.layer_tap.val) : layer_off(action.layer_tap.val); | ||
| 506 | break; | ||
| 507 | case OP_OFF_ON: | ||
| 508 | event.pressed ? layer_off(action.layer_tap.val) : layer_on(action.layer_tap.val); | ||
| 509 | break; | ||
| 510 | case OP_SET_CLEAR: | ||
| 511 | event.pressed ? layer_move(action.layer_tap.val) : layer_clear(); | ||
| 512 | break; | ||
| 513 | # ifndef NO_ACTION_ONESHOT | ||
| 514 | case OP_ONESHOT: | ||
| 515 | // Oneshot modifier | ||
| 516 | # if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 | ||
| 517 | do_release_oneshot = false; | ||
| 518 | if (event.pressed) { | ||
| 519 | del_mods(get_oneshot_locked_mods()); | ||
| 520 | if (get_oneshot_layer_state() == ONESHOT_TOGGLED) { | ||
| 521 | reset_oneshot_layer(); | ||
| 522 | layer_off(action.layer_tap.val); | ||
| 523 | break; | ||
| 524 | } else if (tap_count < ONESHOT_TAP_TOGGLE) { | ||
| 525 | layer_on(action.layer_tap.val); | ||
| 526 | set_oneshot_layer(action.layer_tap.val, ONESHOT_START); | ||
| 527 | } | ||
| 528 | } else { | ||
| 529 | add_mods(get_oneshot_locked_mods()); | ||
| 530 | if (tap_count >= ONESHOT_TAP_TOGGLE) { | ||
| 531 | reset_oneshot_layer(); | ||
| 532 | clear_oneshot_locked_mods(); | ||
| 533 | set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED); | ||
| 534 | } else { | ||
| 535 | clear_oneshot_layer_state(ONESHOT_PRESSED); | ||
| 536 | } | ||
| 537 | } | ||
| 538 | # else | ||
| 539 | if (event.pressed) { | ||
| 540 | layer_on(action.layer_tap.val); | ||
| 541 | set_oneshot_layer(action.layer_tap.val, ONESHOT_START); | ||
| 542 | } else { | ||
| 543 | clear_oneshot_layer_state(ONESHOT_PRESSED); | ||
| 544 | if (tap_count > 1) { | ||
| 545 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); | ||
| 546 | } | ||
| 547 | } | ||
| 548 | # endif | ||
| 549 | break; | ||
| 550 | # endif | ||
| 551 | default: | ||
| 552 | /* tap key */ | ||
| 553 | if (event.pressed) { | ||
| 554 | if (tap_count > 0) { | ||
| 555 | dprint("KEYMAP_TAP_KEY: Tap: register_code\n"); | ||
| 556 | register_code(action.layer_tap.code); | ||
| 557 | } else { | ||
| 558 | dprint("KEYMAP_TAP_KEY: No tap: On on press\n"); | ||
| 559 | layer_on(action.layer_tap.val); | ||
| 560 | } | ||
| 561 | } else { | ||
| 562 | if (tap_count > 0) { | ||
| 563 | dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n"); | ||
| 564 | if (action.layer_tap.code == KC_CAPS) { | ||
| 565 | wait_ms(TAP_HOLD_CAPS_DELAY); | ||
| 566 | } else { | ||
| 567 | wait_ms(TAP_CODE_DELAY); | ||
| 568 | } | ||
| 569 | unregister_code(action.layer_tap.code); | ||
| 570 | } else { | ||
| 571 | dprint("KEYMAP_TAP_KEY: No tap: Off on release\n"); | ||
| 572 | layer_off(action.layer_tap.val); | ||
| 573 | } | ||
| 574 | } | ||
| 575 | break; | ||
| 576 | } | ||
| 577 | break; | ||
| 578 | # endif | ||
| 579 | #endif | ||
| 580 | /* Extentions */ | ||
| 581 | #ifndef NO_ACTION_MACRO | ||
| 582 | case ACT_MACRO: | ||
| 583 | action_macro_play(action_get_macro(record, action.func.id, action.func.opt)); | ||
| 584 | break; | ||
| 585 | #endif | ||
| 586 | #ifdef SWAP_HANDS_ENABLE | ||
| 587 | case ACT_SWAP_HANDS: | ||
| 588 | switch (action.swap.code) { | ||
| 589 | case OP_SH_TOGGLE: | ||
| 590 | if (event.pressed) { | ||
| 591 | swap_hands = !swap_hands; | ||
| 592 | } | ||
| 593 | break; | ||
| 594 | case OP_SH_ON_OFF: | ||
| 595 | swap_hands = event.pressed; | ||
| 596 | break; | ||
| 597 | case OP_SH_OFF_ON: | ||
| 598 | swap_hands = !event.pressed; | ||
| 599 | break; | ||
| 600 | case OP_SH_ON: | ||
| 601 | if (!event.pressed) { | ||
| 602 | swap_hands = true; | ||
| 603 | } | ||
| 604 | break; | ||
| 605 | case OP_SH_OFF: | ||
| 606 | if (!event.pressed) { | ||
| 607 | swap_hands = false; | ||
| 608 | } | ||
| 609 | break; | ||
| 610 | # ifndef NO_ACTION_ONESHOT | ||
| 611 | case OP_SH_ONESHOT: | ||
| 612 | if (event.pressed) { | ||
| 613 | set_oneshot_swaphands(); | ||
| 614 | } else { | ||
| 615 | release_oneshot_swaphands(); | ||
| 616 | } | ||
| 617 | break; | ||
| 618 | # endif | ||
| 619 | |||
| 620 | # ifndef NO_ACTION_TAPPING | ||
| 621 | case OP_SH_TAP_TOGGLE: | ||
| 622 | /* tap toggle */ | ||
| 623 | |||
| 624 | if (event.pressed) { | ||
| 625 | if (swap_held) { | ||
| 626 | swap_held = false; | ||
| 627 | } else { | ||
| 628 | swap_hands = !swap_hands; | ||
| 629 | } | ||
| 630 | } else { | ||
| 631 | if (tap_count < TAPPING_TOGGLE) { | ||
| 632 | swap_hands = !swap_hands; | ||
| 633 | } | ||
| 634 | } | ||
| 635 | break; | ||
| 636 | default: | ||
| 637 | /* tap key */ | ||
| 638 | if (tap_count > 0) { | ||
| 639 | if (swap_held) { | ||
| 640 | swap_hands = !swap_hands; // undo hold set up in _tap_hint | ||
| 641 | swap_held = false; | ||
| 642 | } | ||
| 643 | if (event.pressed) { | ||
| 644 | register_code(action.swap.code); | ||
| 645 | } else { | ||
| 646 | wait_ms(TAP_CODE_DELAY); | ||
| 647 | unregister_code(action.swap.code); | ||
| 648 | *record = (keyrecord_t){}; // hack: reset tap mode | ||
| 649 | } | ||
| 650 | } else { | ||
| 651 | if (swap_held && !event.pressed) { | ||
| 652 | swap_hands = !swap_hands; // undo hold set up in _tap_hint | ||
| 653 | swap_held = false; | ||
| 654 | } | ||
| 655 | } | ||
| 656 | # endif | ||
| 657 | } | ||
| 658 | #endif | ||
| 659 | #ifndef NO_ACTION_FUNCTION | ||
| 660 | case ACT_FUNCTION: | ||
| 661 | action_function(record, action.func.id, action.func.opt); | ||
| 662 | break; | ||
| 663 | #endif | ||
| 664 | default: | ||
| 665 | break; | ||
| 666 | } | ||
| 667 | |||
| 668 | #ifndef NO_ACTION_LAYER | ||
| 669 | // if this event is a layer action, update the leds | ||
| 670 | switch (action.kind.id) { | ||
| 671 | case ACT_LAYER: | ||
| 672 | case ACT_LAYER_MODS: | ||
| 673 | # ifndef NO_ACTION_TAPPING | ||
| 674 | case ACT_LAYER_TAP: | ||
| 675 | case ACT_LAYER_TAP_EXT: | ||
| 676 | # endif | ||
| 677 | led_set(host_keyboard_leds()); | ||
| 678 | break; | ||
| 679 | default: | ||
| 680 | break; | ||
| 681 | } | ||
| 682 | #endif | ||
| 683 | |||
| 684 | #ifndef NO_ACTION_TAPPING | ||
| 685 | # if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) | ||
| 686 | if (!is_tap_action(action)) { | ||
| 687 | retro_tapping_counter = 0; | ||
| 688 | } else { | ||
| 689 | if (event.pressed) { | ||
| 690 | if (tap_count > 0) { | ||
| 691 | retro_tapping_counter = 0; | ||
| 692 | } | ||
| 693 | } else { | ||
| 694 | if (tap_count > 0) { | ||
| 695 | retro_tapping_counter = 0; | ||
| 696 | } else { | ||
| 697 | if ( | ||
| 698 | # ifdef RETRO_TAPPING_PER_KEY | ||
| 699 | get_retro_tapping(get_event_keycode(record->event, false), record) && | ||
| 700 | # endif | ||
| 701 | retro_tapping_counter == 2) { | ||
| 702 | tap_code(action.layer_tap.code); | ||
| 703 | } | ||
| 704 | retro_tapping_counter = 0; | ||
| 705 | } | ||
| 706 | } | ||
| 707 | } | ||
| 708 | # endif | ||
| 709 | #endif | ||
| 710 | |||
| 711 | #ifdef SWAP_HANDS_ENABLE | ||
| 712 | # ifndef NO_ACTION_ONESHOT | ||
| 713 | if (event.pressed && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)) { | ||
| 714 | use_oneshot_swaphands(); | ||
| 715 | } | ||
| 716 | # endif | ||
| 717 | #endif | ||
| 718 | |||
| 719 | #ifndef NO_ACTION_ONESHOT | ||
| 720 | /* Because we switch layers after a oneshot event, we need to release the | ||
| 721 | * key before we leave the layer or no key up event will be generated. | ||
| 722 | */ | ||
| 723 | if (do_release_oneshot && !(get_oneshot_layer_state() & ONESHOT_PRESSED)) { | ||
| 724 | record->event.pressed = false; | ||
| 725 | layer_on(get_oneshot_layer()); | ||
| 726 | process_record(record); | ||
| 727 | layer_off(get_oneshot_layer()); | ||
| 728 | } | ||
| 729 | #endif | ||
| 730 | } | ||
| 731 | |||
| 732 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
| 733 | * | ||
| 734 | * FIXME: Needs documentation. | ||
| 735 | */ | ||
| 736 | void register_code(uint8_t code) { | ||
| 737 | if (code == KC_NO) { | ||
| 738 | return; | ||
| 739 | } | ||
| 740 | #ifdef LOCKING_SUPPORT_ENABLE | ||
| 741 | else if (KC_LOCKING_CAPS == code) { | ||
| 742 | # ifdef LOCKING_RESYNC_ENABLE | ||
| 743 | // Resync: ignore if caps lock already is on | ||
| 744 | if (host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK)) return; | ||
| 745 | # endif | ||
| 746 | add_key(KC_CAPSLOCK); | ||
| 747 | send_keyboard_report(); | ||
| 748 | wait_ms(100); | ||
| 749 | del_key(KC_CAPSLOCK); | ||
| 750 | send_keyboard_report(); | ||
| 751 | } | ||
| 752 | |||
| 753 | else if (KC_LOCKING_NUM == code) { | ||
| 754 | # ifdef LOCKING_RESYNC_ENABLE | ||
| 755 | if (host_keyboard_leds() & (1 << USB_LED_NUM_LOCK)) return; | ||
| 756 | # endif | ||
| 757 | add_key(KC_NUMLOCK); | ||
| 758 | send_keyboard_report(); | ||
| 759 | wait_ms(100); | ||
| 760 | del_key(KC_NUMLOCK); | ||
| 761 | send_keyboard_report(); | ||
| 762 | } | ||
| 763 | |||
| 764 | else if (KC_LOCKING_SCROLL == code) { | ||
| 765 | # ifdef LOCKING_RESYNC_ENABLE | ||
| 766 | if (host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK)) return; | ||
| 767 | # endif | ||
| 768 | add_key(KC_SCROLLLOCK); | ||
| 769 | send_keyboard_report(); | ||
| 770 | wait_ms(100); | ||
| 771 | del_key(KC_SCROLLLOCK); | ||
| 772 | send_keyboard_report(); | ||
| 773 | } | ||
| 774 | #endif | ||
| 775 | |||
| 776 | else if IS_KEY (code) { | ||
| 777 | // TODO: should push command_proc out of this block? | ||
| 778 | if (command_proc(code)) return; | ||
| 779 | |||
| 780 | #ifndef NO_ACTION_ONESHOT | ||
| 781 | /* TODO: remove | ||
| 782 | if (oneshot_state.mods && !oneshot_state.disabled) { | ||
| 783 | uint8_t tmp_mods = get_mods(); | ||
| 784 | add_mods(oneshot_state.mods); | ||
| 785 | |||
| 786 | add_key(code); | ||
| 787 | send_keyboard_report(); | ||
| 788 | |||
| 789 | set_mods(tmp_mods); | ||
| 790 | send_keyboard_report(); | ||
| 791 | oneshot_cancel(); | ||
| 792 | } else | ||
| 793 | */ | ||
| 794 | #endif | ||
| 795 | { | ||
| 796 | // Force a new key press if the key is already pressed | ||
| 797 | // without this, keys with the same keycode, but different | ||
| 798 | // modifiers will be reported incorrectly, see issue #1708 | ||
| 799 | if (is_key_pressed(keyboard_report, code)) { | ||
| 800 | del_key(code); | ||
| 801 | send_keyboard_report(); | ||
| 802 | } | ||
| 803 | add_key(code); | ||
| 804 | send_keyboard_report(); | ||
| 805 | } | ||
| 806 | } else if IS_MOD (code) { | ||
| 807 | add_mods(MOD_BIT(code)); | ||
| 808 | send_keyboard_report(); | ||
| 809 | } | ||
| 810 | #ifdef EXTRAKEY_ENABLE | ||
| 811 | else if IS_SYSTEM (code) { | ||
| 812 | host_system_send(KEYCODE2SYSTEM(code)); | ||
| 813 | } else if IS_CONSUMER (code) { | ||
| 814 | host_consumer_send(KEYCODE2CONSUMER(code)); | ||
| 815 | } | ||
| 816 | #endif | ||
| 817 | #ifdef MOUSEKEY_ENABLE | ||
| 818 | else if IS_MOUSEKEY (code) { | ||
| 819 | mousekey_on(code); | ||
| 820 | mousekey_send(); | ||
| 821 | } | ||
| 822 | #endif | ||
| 823 | } | ||
| 824 | |||
| 825 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
| 826 | * | ||
| 827 | * FIXME: Needs documentation. | ||
| 828 | */ | ||
| 829 | void unregister_code(uint8_t code) { | ||
| 830 | if (code == KC_NO) { | ||
| 831 | return; | ||
| 832 | } | ||
| 833 | #ifdef LOCKING_SUPPORT_ENABLE | ||
| 834 | else if (KC_LOCKING_CAPS == code) { | ||
| 835 | # ifdef LOCKING_RESYNC_ENABLE | ||
| 836 | // Resync: ignore if caps lock already is off | ||
| 837 | if (!(host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK))) return; | ||
| 838 | # endif | ||
| 839 | add_key(KC_CAPSLOCK); | ||
| 840 | send_keyboard_report(); | ||
| 841 | del_key(KC_CAPSLOCK); | ||
| 842 | send_keyboard_report(); | ||
| 843 | } | ||
| 844 | |||
| 845 | else if (KC_LOCKING_NUM == code) { | ||
| 846 | # ifdef LOCKING_RESYNC_ENABLE | ||
| 847 | if (!(host_keyboard_leds() & (1 << USB_LED_NUM_LOCK))) return; | ||
| 848 | # endif | ||
| 849 | add_key(KC_NUMLOCK); | ||
| 850 | send_keyboard_report(); | ||
| 851 | del_key(KC_NUMLOCK); | ||
| 852 | send_keyboard_report(); | ||
| 853 | } | ||
| 854 | |||
| 855 | else if (KC_LOCKING_SCROLL == code) { | ||
| 856 | # ifdef LOCKING_RESYNC_ENABLE | ||
| 857 | if (!(host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK))) return; | ||
| 858 | # endif | ||
| 859 | add_key(KC_SCROLLLOCK); | ||
| 860 | send_keyboard_report(); | ||
| 861 | del_key(KC_SCROLLLOCK); | ||
| 862 | send_keyboard_report(); | ||
| 863 | } | ||
| 864 | #endif | ||
| 865 | |||
| 866 | else if IS_KEY (code) { | ||
| 867 | del_key(code); | ||
| 868 | send_keyboard_report(); | ||
| 869 | } else if IS_MOD (code) { | ||
| 870 | del_mods(MOD_BIT(code)); | ||
| 871 | send_keyboard_report(); | ||
| 872 | } else if IS_SYSTEM (code) { | ||
| 873 | host_system_send(0); | ||
| 874 | } else if IS_CONSUMER (code) { | ||
| 875 | host_consumer_send(0); | ||
| 876 | } | ||
| 877 | #ifdef MOUSEKEY_ENABLE | ||
| 878 | else if IS_MOUSEKEY (code) { | ||
| 879 | mousekey_off(code); | ||
| 880 | mousekey_send(); | ||
| 881 | } | ||
| 882 | #endif | ||
| 883 | } | ||
| 884 | |||
| 885 | /** \brief Tap a keycode with a delay. | ||
| 886 | * | ||
| 887 | * \param code The basic keycode to tap. | ||
| 888 | * \param delay The amount of time in milliseconds to leave the keycode registered, before unregistering it. | ||
| 889 | */ | ||
| 890 | void tap_code_delay(uint8_t code, uint16_t delay) { | ||
| 891 | register_code(code); | ||
| 892 | for (uint16_t i = delay; i > 0; i--) { | ||
| 893 | wait_ms(1); | ||
| 894 | } | ||
| 895 | unregister_code(code); | ||
| 896 | } | ||
| 897 | |||
| 898 | /** \brief Tap a keycode with the default delay. | ||
| 899 | * | ||
| 900 | * \param code The basic keycode to tap. If `code` is `KC_CAPS`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined. | ||
| 901 | */ | ||
| 902 | void tap_code(uint8_t code) { tap_code_delay(code, code == KC_CAPS ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); } | ||
| 903 | |||
| 904 | /** \brief Adds the given physically pressed modifiers and sends a keyboard report immediately. | ||
| 905 | * | ||
| 906 | * \param mods A bitfield of modifiers to register. | ||
| 907 | */ | ||
| 908 | void register_mods(uint8_t mods) { | ||
| 909 | if (mods) { | ||
| 910 | add_mods(mods); | ||
| 911 | send_keyboard_report(); | ||
| 912 | } | ||
| 913 | } | ||
| 914 | |||
| 915 | /** \brief Removes the given physically pressed modifiers and sends a keyboard report immediately. | ||
| 916 | * | ||
| 917 | * \param mods A bitfield of modifiers to unregister. | ||
| 918 | */ | ||
| 919 | void unregister_mods(uint8_t mods) { | ||
| 920 | if (mods) { | ||
| 921 | del_mods(mods); | ||
| 922 | send_keyboard_report(); | ||
| 923 | } | ||
| 924 | } | ||
| 925 | |||
| 926 | /** \brief Adds the given weak modifiers and sends a keyboard report immediately. | ||
| 927 | * | ||
| 928 | * \param mods A bitfield of modifiers to register. | ||
| 929 | */ | ||
| 930 | void register_weak_mods(uint8_t mods) { | ||
| 931 | if (mods) { | ||
| 932 | add_weak_mods(mods); | ||
| 933 | send_keyboard_report(); | ||
| 934 | } | ||
| 935 | } | ||
| 936 | |||
| 937 | /** \brief Removes the given weak modifiers and sends a keyboard report immediately. | ||
| 938 | * | ||
| 939 | * \param mods A bitfield of modifiers to unregister. | ||
| 940 | */ | ||
| 941 | void unregister_weak_mods(uint8_t mods) { | ||
| 942 | if (mods) { | ||
| 943 | del_weak_mods(mods); | ||
| 944 | send_keyboard_report(); | ||
| 945 | } | ||
| 946 | } | ||
| 947 | |||
| 948 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
| 949 | * | ||
| 950 | * FIXME: Needs documentation. | ||
| 951 | */ | ||
| 952 | void clear_keyboard(void) { | ||
| 953 | clear_mods(); | ||
| 954 | clear_keyboard_but_mods(); | ||
| 955 | } | ||
| 956 | |||
| 957 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
| 958 | * | ||
| 959 | * FIXME: Needs documentation. | ||
| 960 | */ | ||
| 961 | void clear_keyboard_but_mods(void) { | ||
| 962 | clear_keys(); | ||
| 963 | clear_keyboard_but_mods_and_keys(); | ||
| 964 | } | ||
| 965 | |||
| 966 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
| 967 | * | ||
| 968 | * FIXME: Needs documentation. | ||
| 969 | */ | ||
| 970 | void clear_keyboard_but_mods_and_keys() { | ||
| 971 | #ifdef EXTRAKEY_ENABLE | ||
| 972 | host_system_send(0); | ||
| 973 | host_consumer_send(0); | ||
| 974 | #endif | ||
| 975 | clear_weak_mods(); | ||
| 976 | clear_macro_mods(); | ||
| 977 | send_keyboard_report(); | ||
| 978 | #ifdef MOUSEKEY_ENABLE | ||
| 979 | mousekey_clear(); | ||
| 980 | mousekey_send(); | ||
| 981 | #endif | ||
| 982 | } | ||
| 983 | |||
| 984 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
| 985 | * | ||
| 986 | * FIXME: Needs documentation. | ||
| 987 | */ | ||
| 988 | bool is_tap_key(keypos_t key) { | ||
| 989 | action_t action = layer_switch_get_action(key); | ||
| 990 | return is_tap_action(action); | ||
| 991 | } | ||
| 992 | |||
| 993 | /** \brief Utilities for actions. (FIXME: Needs better description) | ||
| 994 | * | ||
| 995 | * FIXME: Needs documentation. | ||
| 996 | */ | ||
| 997 | bool is_tap_action(action_t action) { | ||
| 998 | switch (action.kind.id) { | ||
| 999 | case ACT_LMODS_TAP: | ||
| 1000 | case ACT_RMODS_TAP: | ||
| 1001 | case ACT_LAYER_TAP: | ||
| 1002 | case ACT_LAYER_TAP_EXT: | ||
| 1003 | switch (action.layer_tap.code) { | ||
| 1004 | case KC_NO ... KC_RGUI: | ||
| 1005 | case OP_TAP_TOGGLE: | ||
| 1006 | case OP_ONESHOT: | ||
| 1007 | return true; | ||
| 1008 | } | ||
| 1009 | return false; | ||
| 1010 | case ACT_SWAP_HANDS: | ||
| 1011 | switch (action.swap.code) { | ||
| 1012 | case KC_NO ... KC_RGUI: | ||
| 1013 | case OP_SH_TAP_TOGGLE: | ||
| 1014 | return true; | ||
| 1015 | } | ||
| 1016 | return false; | ||
| 1017 | case ACT_MACRO: | ||
| 1018 | case ACT_FUNCTION: | ||
| 1019 | if (action.func.opt & FUNC_TAP) { | ||
| 1020 | return true; | ||
| 1021 | } | ||
| 1022 | return false; | ||
| 1023 | } | ||
| 1024 | return false; | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | /** \brief Debug print (FIXME: Needs better description) | ||
| 1028 | * | ||
| 1029 | * FIXME: Needs documentation. | ||
| 1030 | */ | ||
| 1031 | void debug_event(keyevent_t event) { dprintf("%04X%c(%u)", (event.key.row << 8 | event.key.col), (event.pressed ? 'd' : 'u'), event.time); } | ||
| 1032 | /** \brief Debug print (FIXME: Needs better description) | ||
| 1033 | * | ||
| 1034 | * FIXME: Needs documentation. | ||
| 1035 | */ | ||
| 1036 | void debug_record(keyrecord_t record) { | ||
| 1037 | debug_event(record.event); | ||
| 1038 | #ifndef NO_ACTION_TAPPING | ||
| 1039 | dprintf(":%u%c", record.tap.count, (record.tap.interrupted ? '-' : ' ')); | ||
| 1040 | #endif | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | /** \brief Debug print (FIXME: Needs better description) | ||
| 1044 | * | ||
| 1045 | * FIXME: Needs documentation. | ||
| 1046 | */ | ||
| 1047 | void debug_action(action_t action) { | ||
| 1048 | switch (action.kind.id) { | ||
| 1049 | case ACT_LMODS: | ||
| 1050 | dprint("ACT_LMODS"); | ||
| 1051 | break; | ||
| 1052 | case ACT_RMODS: | ||
| 1053 | dprint("ACT_RMODS"); | ||
| 1054 | break; | ||
| 1055 | case ACT_LMODS_TAP: | ||
| 1056 | dprint("ACT_LMODS_TAP"); | ||
| 1057 | break; | ||
| 1058 | case ACT_RMODS_TAP: | ||
| 1059 | dprint("ACT_RMODS_TAP"); | ||
| 1060 | break; | ||
| 1061 | case ACT_USAGE: | ||
| 1062 | dprint("ACT_USAGE"); | ||
| 1063 | break; | ||
| 1064 | case ACT_MOUSEKEY: | ||
| 1065 | dprint("ACT_MOUSEKEY"); | ||
| 1066 | break; | ||
| 1067 | case ACT_LAYER: | ||
| 1068 | dprint("ACT_LAYER"); | ||
| 1069 | break; | ||
| 1070 | case ACT_LAYER_MODS: | ||
| 1071 | dprint("ACT_LAYER_MODS"); | ||
| 1072 | break; | ||
| 1073 | case ACT_LAYER_TAP: | ||
| 1074 | dprint("ACT_LAYER_TAP"); | ||
| 1075 | break; | ||
| 1076 | case ACT_LAYER_TAP_EXT: | ||
| 1077 | dprint("ACT_LAYER_TAP_EXT"); | ||
| 1078 | break; | ||
| 1079 | case ACT_MACRO: | ||
| 1080 | dprint("ACT_MACRO"); | ||
| 1081 | break; | ||
| 1082 | case ACT_FUNCTION: | ||
| 1083 | dprint("ACT_FUNCTION"); | ||
| 1084 | break; | ||
| 1085 | case ACT_SWAP_HANDS: | ||
| 1086 | dprint("ACT_SWAP_HANDS"); | ||
| 1087 | break; | ||
| 1088 | default: | ||
| 1089 | dprint("UNKNOWN"); | ||
| 1090 | break; | ||
| 1091 | } | ||
| 1092 | dprintf("[%X:%02X]", action.kind.param >> 8, action.kind.param & 0xff); | ||
| 1093 | } | ||
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h deleted file mode 100644 index 8cb4722c6..000000000 --- a/tmk_core/common/action.h +++ /dev/null | |||
| @@ -1,127 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2012,2013 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <stdint.h> | ||
| 21 | #include <stdbool.h> | ||
| 22 | #include "keyboard.h" | ||
| 23 | #include "keycode.h" | ||
| 24 | #include "action_code.h" | ||
| 25 | #include "action_macro.h" | ||
| 26 | |||
| 27 | #ifdef __cplusplus | ||
| 28 | extern "C" { | ||
| 29 | #endif | ||
| 30 | |||
| 31 | /* Disable macro and function features when LTO is enabled, since they break */ | ||
| 32 | #ifdef LTO_ENABLE | ||
| 33 | # ifndef NO_ACTION_MACRO | ||
| 34 | # define NO_ACTION_MACRO | ||
| 35 | # endif | ||
| 36 | # ifndef NO_ACTION_FUNCTION | ||
| 37 | # define NO_ACTION_FUNCTION | ||
| 38 | # endif | ||
| 39 | #endif | ||
| 40 | |||
| 41 | /* tapping count and state */ | ||
| 42 | typedef struct { | ||
| 43 | bool interrupted : 1; | ||
| 44 | bool reserved2 : 1; | ||
| 45 | bool reserved1 : 1; | ||
| 46 | bool reserved0 : 1; | ||
| 47 | uint8_t count : 4; | ||
| 48 | } tap_t; | ||
| 49 | |||
| 50 | /* Key event container for recording */ | ||
| 51 | typedef struct { | ||
| 52 | keyevent_t event; | ||
| 53 | #ifndef NO_ACTION_TAPPING | ||
| 54 | tap_t tap; | ||
| 55 | #endif | ||
| 56 | } keyrecord_t; | ||
| 57 | |||
| 58 | /* Execute action per keyevent */ | ||
| 59 | void action_exec(keyevent_t event); | ||
| 60 | |||
| 61 | /* action for key */ | ||
| 62 | action_t action_for_key(uint8_t layer, keypos_t key); | ||
| 63 | |||
| 64 | /* macro */ | ||
| 65 | const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt); | ||
| 66 | |||
| 67 | /* user defined special function */ | ||
| 68 | void action_function(keyrecord_t *record, uint8_t id, uint8_t opt); | ||
| 69 | |||
| 70 | /* keyboard-specific key event (pre)processing */ | ||
| 71 | bool process_record_quantum(keyrecord_t *record); | ||
| 72 | |||
| 73 | /* Utilities for actions. */ | ||
| 74 | #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) | ||
| 75 | extern bool disable_action_cache; | ||
| 76 | #endif | ||
| 77 | |||
| 78 | /* Code for handling one-handed key modifiers. */ | ||
| 79 | #ifdef SWAP_HANDS_ENABLE | ||
| 80 | extern bool swap_hands; | ||
| 81 | extern const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS]; | ||
| 82 | # if (MATRIX_COLS <= 8) | ||
| 83 | typedef uint8_t swap_state_row_t; | ||
| 84 | # elif (MATRIX_COLS <= 16) | ||
| 85 | typedef uint16_t swap_state_row_t; | ||
| 86 | # elif (MATRIX_COLS <= 32) | ||
| 87 | typedef uint32_t swap_state_row_t; | ||
| 88 | # else | ||
| 89 | # error "MATRIX_COLS: invalid value" | ||
| 90 | # endif | ||
| 91 | |||
| 92 | void process_hand_swap(keyevent_t *record); | ||
| 93 | #endif | ||
| 94 | |||
| 95 | void process_record_nocache(keyrecord_t *record); | ||
| 96 | void process_record(keyrecord_t *record); | ||
| 97 | void process_record_handler(keyrecord_t *record); | ||
| 98 | void post_process_record_quantum(keyrecord_t *record); | ||
| 99 | void process_action(keyrecord_t *record, action_t action); | ||
| 100 | void register_code(uint8_t code); | ||
| 101 | void unregister_code(uint8_t code); | ||
| 102 | void tap_code(uint8_t code); | ||
| 103 | void tap_code_delay(uint8_t code, uint16_t delay); | ||
| 104 | void register_mods(uint8_t mods); | ||
| 105 | void unregister_mods(uint8_t mods); | ||
| 106 | void register_weak_mods(uint8_t mods); | ||
| 107 | void unregister_weak_mods(uint8_t mods); | ||
| 108 | // void set_mods(uint8_t mods); | ||
| 109 | void clear_keyboard(void); | ||
| 110 | void clear_keyboard_but_mods(void); | ||
| 111 | void clear_keyboard_but_mods_and_keys(void); | ||
| 112 | void layer_switch(uint8_t new_layer); | ||
| 113 | bool is_tap_key(keypos_t key); | ||
| 114 | bool is_tap_action(action_t action); | ||
| 115 | |||
| 116 | #ifndef NO_ACTION_TAPPING | ||
| 117 | void process_record_tap_hint(keyrecord_t *record); | ||
| 118 | #endif | ||
| 119 | |||
| 120 | /* debug */ | ||
| 121 | void debug_event(keyevent_t event); | ||
| 122 | void debug_record(keyrecord_t record); | ||
| 123 | void debug_action(action_t action); | ||
| 124 | |||
| 125 | #ifdef __cplusplus | ||
| 126 | } | ||
| 127 | #endif | ||
diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h deleted file mode 100644 index eb18c36ae..000000000 --- a/tmk_core/common/action_code.h +++ /dev/null | |||
| @@ -1,308 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | /** \brief Action codes | ||
| 21 | * | ||
| 22 | * 16bit code: action_kind(4bit) + action_parameter(12bit) | ||
| 23 | * | ||
| 24 | * Key Actions(00xx) | ||
| 25 | * ----------------- | ||
| 26 | * ACT_MODS(000r): | ||
| 27 | * 000r|0000|0000 0000 No action code | ||
| 28 | * 000r|0000|0000 0001 Transparent code | ||
| 29 | * 000r|0000| keycode Key | ||
| 30 | * 000r|mods|0000 0000 Modifiers | ||
| 31 | * 000r|mods| keycode Modifiers+Key(Modified key) | ||
| 32 | * r: Left/Right flag(Left:0, Right:1) | ||
| 33 | * | ||
| 34 | * ACT_MODS_TAP(001r): | ||
| 35 | * 001r|mods|0000 0000 Modifiers with OneShot | ||
| 36 | * 001r|mods|0000 0001 Modifiers with tap toggle | ||
| 37 | * 001r|mods|0000 00xx (reserved) | ||
| 38 | * 001r|mods| keycode Modifiers with Tap Key(Dual role) | ||
| 39 | * | ||
| 40 | * Other Keys(01xx) | ||
| 41 | * ---------------- | ||
| 42 | * ACT_USAGE(0100): TODO: Not needed? | ||
| 43 | * 0100|00| usage(10) System control(0x80) - General Desktop page(0x01) | ||
| 44 | * 0100|01| usage(10) Consumer control(0x01) - Consumer page(0x0C) | ||
| 45 | * 0100|10| usage(10) (reserved) | ||
| 46 | * 0100|11| usage(10) (reserved) | ||
| 47 | * | ||
| 48 | * ACT_MOUSEKEY(0101): TODO: Merge these two actions to conserve space? | ||
| 49 | * 0101|xxxx| keycode Mouse key | ||
| 50 | * | ||
| 51 | * ACT_SWAP_HANDS(0110): | ||
| 52 | * 0110|xxxx| keycode Swap hands (keycode on tap, or options) | ||
| 53 | * | ||
| 54 | * 0111|xxxx xxxx xxxx (reserved) | ||
| 55 | * | ||
| 56 | * Layer Actions(10xx) | ||
| 57 | * ------------------- | ||
| 58 | * ACT_LAYER(1000): | ||
| 59 | * 1000|oo00|pppE BBBB Default Layer Bitwise operation | ||
| 60 | * oo: operation(00:AND, 01:OR, 10:XOR, 11:SET) | ||
| 61 | * ppp: 4-bit chunk part(0-7) | ||
| 62 | * EBBBB: bits and extra bit | ||
| 63 | * 1000|ooee|pppE BBBB Layer Bitwise Operation | ||
| 64 | * oo: operation(00:AND, 01:OR, 10:XOR, 11:SET) | ||
| 65 | * ppp: 4-bit chunk part(0-7) | ||
| 66 | * EBBBB: bits and extra bit | ||
| 67 | * ee: on event(01:press, 10:release, 11:both) | ||
| 68 | * | ||
| 69 | * ACT_LAYER_MODS(1001): | ||
| 70 | * 1001|LLLL| mods Layer with modifiers held | ||
| 71 | * | ||
| 72 | * ACT_LAYER_TAP(101x): | ||
| 73 | * 101E|LLLL| keycode On/Off with tap key (0x00-DF)[TAP] | ||
| 74 | * 101E|LLLL|1110 mods On/Off with modifiers (0xE0-EF)[NOT TAP] | ||
| 75 | * 101E|LLLL|1111 0000 Invert with tap toggle (0xF0) [TAP] | ||
| 76 | * 101E|LLLL|1111 0001 On/Off (0xF1) [NOT TAP] | ||
| 77 | * 101E|LLLL|1111 0010 Off/On (0xF2) [NOT TAP] | ||
| 78 | * 101E|LLLL|1111 0011 Set/Clear (0xF3) [NOT TAP] | ||
| 79 | * 101E|LLLL|1111 0100 One Shot Layer (0xF4) [TAP] | ||
| 80 | * 101E|LLLL|1111 xxxx Reserved (0xF5-FF) | ||
| 81 | * ELLLL: layer 0-31(E: extra bit for layer 16-31) | ||
| 82 | * | ||
| 83 | * Extensions(11xx) | ||
| 84 | * ---------------- | ||
| 85 | * ACT_MACRO(1100): | ||
| 86 | * 1100|opt | id(8) Macro play? | ||
| 87 | * 1100|1111| id(8) Macro record? | ||
| 88 | * | ||
| 89 | * 1101|xxxx xxxx xxxx (reserved) | ||
| 90 | * 1110|xxxx xxxx xxxx (reserved) | ||
| 91 | * | ||
| 92 | * ACT_FUNCTION(1111): | ||
| 93 | * 1111| address(12) Function? | ||
| 94 | * 1111|opt | id(8) Function? | ||
| 95 | */ | ||
| 96 | enum action_kind_id { | ||
| 97 | /* Key Actions */ | ||
| 98 | ACT_MODS = 0b0000, | ||
| 99 | ACT_LMODS = 0b0000, | ||
| 100 | ACT_RMODS = 0b0001, | ||
| 101 | ACT_MODS_TAP = 0b0010, | ||
| 102 | ACT_LMODS_TAP = 0b0010, | ||
| 103 | ACT_RMODS_TAP = 0b0011, | ||
| 104 | /* Other Keys */ | ||
| 105 | ACT_USAGE = 0b0100, | ||
| 106 | ACT_MOUSEKEY = 0b0101, | ||
| 107 | /* One-hand Support */ | ||
| 108 | ACT_SWAP_HANDS = 0b0110, | ||
| 109 | /* Layer Actions */ | ||
| 110 | ACT_LAYER = 0b1000, | ||
| 111 | ACT_LAYER_MODS = 0b1001, | ||
| 112 | ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */ | ||
| 113 | ACT_LAYER_TAP_EXT = 0b1011, /* Layer 16-31 */ | ||
| 114 | /* Extensions */ | ||
| 115 | ACT_MACRO = 0b1100, | ||
| 116 | ACT_FUNCTION = 0b1111 | ||
| 117 | }; | ||
| 118 | |||
| 119 | /** \brief Action Code Struct | ||
| 120 | * | ||
| 121 | * NOTE: | ||
| 122 | * In avr-gcc bit field seems to be assigned from LSB(bit0) to MSB(bit15). | ||
| 123 | * AVR looks like a little endian in avr-gcc. | ||
| 124 | * Not portable across compiler/endianness? | ||
| 125 | * | ||
| 126 | * Byte order and bit order of 0x1234: | ||
| 127 | * Big endian: Little endian: | ||
| 128 | * -------------------- -------------------- | ||
| 129 | * FEDC BA98 7654 3210 0123 4567 89AB CDEF | ||
| 130 | * 0001 0010 0011 0100 0010 1100 0100 1000 | ||
| 131 | * 0x12 0x34 0x34 0x12 | ||
| 132 | */ | ||
| 133 | typedef union { | ||
| 134 | uint16_t code; | ||
| 135 | struct action_kind { | ||
| 136 | uint16_t param : 12; | ||
| 137 | uint8_t id : 4; | ||
| 138 | } kind; | ||
| 139 | struct action_key { | ||
| 140 | uint8_t code : 8; | ||
| 141 | uint8_t mods : 4; | ||
| 142 | uint8_t kind : 4; | ||
| 143 | } key; | ||
| 144 | struct action_layer_bitop { | ||
| 145 | uint8_t bits : 4; | ||
| 146 | uint8_t xbit : 1; | ||
| 147 | uint8_t part : 3; | ||
| 148 | uint8_t on : 2; | ||
| 149 | uint8_t op : 2; | ||
| 150 | uint8_t kind : 4; | ||
| 151 | } layer_bitop; | ||
| 152 | struct action_layer_mods { | ||
| 153 | uint8_t mods : 8; | ||
| 154 | uint8_t layer : 4; | ||
| 155 | uint8_t kind : 4; | ||
| 156 | } layer_mods; | ||
| 157 | struct action_layer_tap { | ||
| 158 | uint8_t code : 8; | ||
| 159 | uint8_t val : 5; | ||
| 160 | uint8_t kind : 3; | ||
| 161 | } layer_tap; | ||
| 162 | struct action_usage { | ||
| 163 | uint16_t code : 10; | ||
| 164 | uint8_t page : 2; | ||
| 165 | uint8_t kind : 4; | ||
| 166 | } usage; | ||
| 167 | struct action_function { | ||
| 168 | uint8_t id : 8; | ||
| 169 | uint8_t opt : 4; | ||
| 170 | uint8_t kind : 4; | ||
| 171 | } func; | ||
| 172 | struct action_swap { | ||
| 173 | uint8_t code : 8; | ||
| 174 | uint8_t opt : 4; | ||
| 175 | uint8_t kind : 4; | ||
| 176 | } swap; | ||
| 177 | } action_t; | ||
| 178 | |||
| 179 | /* action utility */ | ||
| 180 | #define ACTION_NO 0 | ||
| 181 | #define ACTION_TRANSPARENT 1 | ||
| 182 | #define ACTION(kind, param) ((kind) << 12 | (param)) | ||
| 183 | |||
| 184 | /** \brief Key Actions | ||
| 185 | * | ||
| 186 | * Mod bits: 43210 | ||
| 187 | * bit 0 ||||+- Control | ||
| 188 | * bit 1 |||+-- Shift | ||
| 189 | * bit 2 ||+--- Alt | ||
| 190 | * bit 3 |+---- Gui | ||
| 191 | * bit 4 +----- LR flag(Left:0, Right:1) | ||
| 192 | */ | ||
| 193 | enum mods_bit { | ||
| 194 | MOD_LCTL = 0x01, | ||
| 195 | MOD_LSFT = 0x02, | ||
| 196 | MOD_LALT = 0x04, | ||
| 197 | MOD_LGUI = 0x08, | ||
| 198 | MOD_RCTL = 0x11, | ||
| 199 | MOD_RSFT = 0x12, | ||
| 200 | MOD_RALT = 0x14, | ||
| 201 | MOD_RGUI = 0x18, | ||
| 202 | }; | ||
| 203 | enum mods_codes { | ||
| 204 | MODS_ONESHOT = 0x00, | ||
| 205 | MODS_TAP_TOGGLE = 0x01, | ||
| 206 | }; | ||
| 207 | #define ACTION_KEY(key) ACTION(ACT_MODS, (key)) | ||
| 208 | #define ACTION_MODS(mods) ACTION(ACT_MODS, ((mods)&0x1f) << 8 | 0) | ||
| 209 | #define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, ((mods)&0x1f) << 8 | (key)) | ||
| 210 | #define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | (key)) | ||
| 211 | #define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | MODS_ONESHOT) | ||
| 212 | #define ACTION_MODS_TAP_TOGGLE(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | MODS_TAP_TOGGLE) | ||
| 213 | |||
| 214 | /** \brief Other Keys | ||
| 215 | */ | ||
| 216 | enum usage_pages { PAGE_SYSTEM, PAGE_CONSUMER }; | ||
| 217 | #define ACTION_USAGE_SYSTEM(id) ACTION(ACT_USAGE, PAGE_SYSTEM << 10 | (id)) | ||
| 218 | #define ACTION_USAGE_CONSUMER(id) ACTION(ACT_USAGE, PAGE_CONSUMER << 10 | (id)) | ||
| 219 | #define ACTION_MOUSEKEY(key) ACTION(ACT_MOUSEKEY, key) | ||
| 220 | |||
| 221 | /** \brief Layer Actions | ||
| 222 | */ | ||
| 223 | enum layer_param_on { | ||
| 224 | ON_PRESS = 1, | ||
| 225 | ON_RELEASE = 2, | ||
| 226 | ON_BOTH = 3, | ||
| 227 | }; | ||
| 228 | |||
| 229 | /** \brief Layer Actions | ||
| 230 | */ | ||
| 231 | enum layer_param_bit_op { | ||
| 232 | OP_BIT_AND = 0, | ||
| 233 | OP_BIT_OR = 1, | ||
| 234 | OP_BIT_XOR = 2, | ||
| 235 | OP_BIT_SET = 3, | ||
| 236 | }; | ||
| 237 | |||
| 238 | /** \brief Layer Actions | ||
| 239 | */ | ||
| 240 | enum layer_param_tap_op { | ||
| 241 | OP_TAP_TOGGLE = 0xF0, | ||
| 242 | OP_ON_OFF, | ||
| 243 | OP_OFF_ON, | ||
| 244 | OP_SET_CLEAR, | ||
| 245 | OP_ONESHOT, | ||
| 246 | }; | ||
| 247 | #define ACTION_LAYER_BITOP(op, part, bits, on) ACTION(ACT_LAYER, (op) << 10 | (on) << 8 | (part) << 5 | ((bits)&0x1f)) | ||
| 248 | #define ACTION_LAYER_TAP(layer, key) ACTION(ACT_LAYER_TAP, (layer) << 8 | (key)) | ||
| 249 | /* Default Layer */ | ||
| 250 | #define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_BIT_SET((layer) / 4, 1 << ((layer) % 4)) | ||
| 251 | /* Layer Operation */ | ||
| 252 | #define ACTION_LAYER_CLEAR(on) ACTION_LAYER_BIT_AND(0, 0, (on)) | ||
| 253 | #define ACTION_LAYER_MOMENTARY(layer) ACTION_LAYER_ON_OFF(layer) | ||
| 254 | #define ACTION_LAYER_TOGGLE(layer) ACTION_LAYER_INVERT(layer, ON_RELEASE) | ||
| 255 | #define ACTION_LAYER_INVERT(layer, on) ACTION_LAYER_BIT_XOR((layer) / 4, 1 << ((layer) % 4), (on)) | ||
| 256 | #define ACTION_LAYER_ON(layer, on) ACTION_LAYER_BIT_OR((layer) / 4, 1 << ((layer) % 4), (on)) | ||
| 257 | #define ACTION_LAYER_OFF(layer, on) ACTION_LAYER_BIT_AND((layer) / 4, ~(1 << ((layer) % 4)), (on)) | ||
| 258 | #define ACTION_LAYER_SET(layer, on) ACTION_LAYER_BIT_SET((layer) / 4, 1 << ((layer) % 4), (on)) | ||
| 259 | #define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF) | ||
| 260 | #define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON) | ||
| 261 | #define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR) | ||
| 262 | #define ACTION_LAYER_ONESHOT(layer) ACTION_LAYER_TAP((layer), OP_ONESHOT) | ||
| 263 | #define ACTION_LAYER_MODS(layer, mods) ACTION(ACT_LAYER_MODS, (layer) << 8 | (mods)) | ||
| 264 | /* With Tapping */ | ||
| 265 | #define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key)) | ||
| 266 | #define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE) | ||
| 267 | /* Bitwise Operation */ | ||
| 268 | #define ACTION_LAYER_BIT_AND(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), (on)) | ||
| 269 | #define ACTION_LAYER_BIT_OR(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), (on)) | ||
| 270 | #define ACTION_LAYER_BIT_XOR(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), (on)) | ||
| 271 | #define ACTION_LAYER_BIT_SET(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), (on)) | ||
| 272 | /* Default Layer Bitwise Operation */ | ||
| 273 | #define ACTION_DEFAULT_LAYER_BIT_AND(part, bits) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), 0) | ||
| 274 | #define ACTION_DEFAULT_LAYER_BIT_OR(part, bits) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), 0) | ||
| 275 | #define ACTION_DEFAULT_LAYER_BIT_XOR(part, bits) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), 0) | ||
| 276 | #define ACTION_DEFAULT_LAYER_BIT_SET(part, bits) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), 0) | ||
| 277 | |||
| 278 | /* Macro */ | ||
| 279 | #define ACTION_MACRO(id) ACTION(ACT_MACRO, (id)) | ||
| 280 | #define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP << 8 | (id)) | ||
| 281 | #define ACTION_MACRO_OPT(id, opt) ACTION(ACT_MACRO, (opt) << 8 | (id)) | ||
| 282 | /* Function */ | ||
| 283 | enum function_opts { | ||
| 284 | FUNC_TAP = 0x8, /* indciates function is tappable */ | ||
| 285 | }; | ||
| 286 | #define ACTION_FUNCTION(id) ACTION(ACT_FUNCTION, (id)) | ||
| 287 | #define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP << 8 | (id)) | ||
| 288 | #define ACTION_FUNCTION_OPT(id, opt) ACTION(ACT_FUNCTION, (opt) << 8 | (id)) | ||
| 289 | /* OneHand Support */ | ||
| 290 | enum swap_hands_param_tap_op { | ||
| 291 | OP_SH_TOGGLE = 0xF0, | ||
| 292 | OP_SH_TAP_TOGGLE, | ||
| 293 | OP_SH_ON_OFF, | ||
| 294 | OP_SH_OFF_ON, | ||
| 295 | OP_SH_OFF, | ||
| 296 | OP_SH_ON, | ||
| 297 | OP_SH_ONESHOT, | ||
| 298 | }; | ||
| 299 | |||
| 300 | #define ACTION_SWAP_HANDS() ACTION_SWAP_HANDS_ON_OFF() | ||
| 301 | #define ACTION_SWAP_HANDS_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TOGGLE) | ||
| 302 | #define ACTION_SWAP_HANDS_TAP_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TAP_TOGGLE) | ||
| 303 | #define ACTION_SWAP_HANDS_ONESHOT() ACTION(ACT_SWAP_HANDS, OP_SH_ONESHOT) | ||
| 304 | #define ACTION_SWAP_HANDS_TAP_KEY(key) ACTION(ACT_SWAP_HANDS, key) | ||
| 305 | #define ACTION_SWAP_HANDS_ON_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_ON_OFF) | ||
| 306 | #define ACTION_SWAP_HANDS_OFF_ON() ACTION(ACT_SWAP_HANDS, OP_SH_OFF_ON) | ||
| 307 | #define ACTION_SWAP_HANDS_ON() ACTION(ACT_SWAP_HANDS, OP_SH_ON) | ||
| 308 | #define ACTION_SWAP_HANDS_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_OFF) | ||
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c deleted file mode 100644 index af2d7d964..000000000 --- a/tmk_core/common/action_layer.c +++ /dev/null | |||
| @@ -1,279 +0,0 @@ | |||
| 1 | #include <stdint.h> | ||
| 2 | #include "keyboard.h" | ||
| 3 | #include "action.h" | ||
| 4 | #include "util.h" | ||
| 5 | #include "action_layer.h" | ||
| 6 | |||
| 7 | #ifdef DEBUG_ACTION | ||
| 8 | # include "debug.h" | ||
| 9 | #else | ||
| 10 | # include "nodebug.h" | ||
| 11 | #endif | ||
| 12 | |||
| 13 | /** \brief Default Layer State | ||
| 14 | */ | ||
| 15 | layer_state_t default_layer_state = 0; | ||
| 16 | |||
| 17 | /** \brief Default Layer State Set At user Level | ||
| 18 | * | ||
| 19 | * Run user code on default layer state change | ||
| 20 | */ | ||
| 21 | __attribute__((weak)) layer_state_t default_layer_state_set_user(layer_state_t state) { return state; } | ||
| 22 | |||
| 23 | /** \brief Default Layer State Set At Keyboard Level | ||
| 24 | * | ||
| 25 | * Run keyboard code on default layer state change | ||
| 26 | */ | ||
| 27 | __attribute__((weak)) layer_state_t default_layer_state_set_kb(layer_state_t state) { return default_layer_state_set_user(state); } | ||
| 28 | |||
| 29 | /** \brief Default Layer State Set | ||
| 30 | * | ||
| 31 | * Static function to set the default layer state, prints debug info and clears keys | ||
| 32 | */ | ||
| 33 | static void default_layer_state_set(layer_state_t state) { | ||
| 34 | state = default_layer_state_set_kb(state); | ||
| 35 | debug("default_layer_state: "); | ||
| 36 | default_layer_debug(); | ||
| 37 | debug(" to "); | ||
| 38 | default_layer_state = state; | ||
| 39 | default_layer_debug(); | ||
| 40 | debug("\n"); | ||
| 41 | #ifdef STRICT_LAYER_RELEASE | ||
| 42 | clear_keyboard_but_mods(); // To avoid stuck keys | ||
| 43 | #else | ||
| 44 | clear_keyboard_but_mods_and_keys(); // Don't reset held keys | ||
| 45 | #endif | ||
| 46 | } | ||
| 47 | |||
| 48 | /** \brief Default Layer Print | ||
| 49 | * | ||
| 50 | * Print out the hex value of the 32-bit default layer state, as well as the value of the highest bit. | ||
| 51 | */ | ||
| 52 | void default_layer_debug(void) { dprintf("%08lX(%u)", default_layer_state, get_highest_layer(default_layer_state)); } | ||
| 53 | |||
| 54 | /** \brief Default Layer Set | ||
| 55 | * | ||
| 56 | * Sets the default layer state. | ||
| 57 | */ | ||
| 58 | void default_layer_set(layer_state_t state) { default_layer_state_set(state); } | ||
| 59 | |||
| 60 | #ifndef NO_ACTION_LAYER | ||
| 61 | /** \brief Default Layer Or | ||
| 62 | * | ||
| 63 | * Turns on the default layer based on matching bits between specifed layer and existing layer state | ||
| 64 | */ | ||
| 65 | void default_layer_or(layer_state_t state) { default_layer_state_set(default_layer_state | state); } | ||
| 66 | /** \brief Default Layer And | ||
| 67 | * | ||
| 68 | * Turns on default layer based on matching enabled bits between specifed layer and existing layer state | ||
| 69 | */ | ||
| 70 | void default_layer_and(layer_state_t state) { default_layer_state_set(default_layer_state & state); } | ||
| 71 | /** \brief Default Layer Xor | ||
| 72 | * | ||
| 73 | * Turns on default layer based on non-matching bits between specifed layer and existing layer state | ||
| 74 | */ | ||
| 75 | void default_layer_xor(layer_state_t state) { default_layer_state_set(default_layer_state ^ state); } | ||
| 76 | #endif | ||
| 77 | |||
| 78 | #ifndef NO_ACTION_LAYER | ||
| 79 | /** \brief Keymap Layer State | ||
| 80 | */ | ||
| 81 | layer_state_t layer_state = 0; | ||
| 82 | |||
| 83 | /** \brief Layer state set user | ||
| 84 | * | ||
| 85 | * Runs user code on layer state change | ||
| 86 | */ | ||
| 87 | __attribute__((weak)) layer_state_t layer_state_set_user(layer_state_t state) { return state; } | ||
| 88 | |||
| 89 | /** \brief Layer state set keyboard | ||
| 90 | * | ||
| 91 | * Runs keyboard code on layer state change | ||
| 92 | */ | ||
| 93 | __attribute__((weak)) layer_state_t layer_state_set_kb(layer_state_t state) { return layer_state_set_user(state); } | ||
| 94 | |||
| 95 | /** \brief Layer state set | ||
| 96 | * | ||
| 97 | * Sets the layer to match the specifed state (a bitmask) | ||
| 98 | */ | ||
| 99 | void layer_state_set(layer_state_t state) { | ||
| 100 | state = layer_state_set_kb(state); | ||
| 101 | dprint("layer_state: "); | ||
| 102 | layer_debug(); | ||
| 103 | dprint(" to "); | ||
| 104 | layer_state = state; | ||
| 105 | layer_debug(); | ||
| 106 | dprintln(); | ||
| 107 | # ifdef STRICT_LAYER_RELEASE | ||
| 108 | clear_keyboard_but_mods(); // To avoid stuck keys | ||
| 109 | # else | ||
| 110 | clear_keyboard_but_mods_and_keys(); // Don't reset held keys | ||
| 111 | # endif | ||
| 112 | } | ||
| 113 | |||
| 114 | /** \brief Layer clear | ||
| 115 | * | ||
| 116 | * Turn off all layers | ||
| 117 | */ | ||
| 118 | void layer_clear(void) { layer_state_set(0); } | ||
| 119 | |||
| 120 | /** \brief Layer state is | ||
| 121 | * | ||
| 122 | * Return whether the given state is on (it might still be shadowed by a higher state, though) | ||
| 123 | */ | ||
| 124 | bool layer_state_is(uint8_t layer) { return layer_state_cmp(layer_state, layer); } | ||
| 125 | |||
| 126 | /** \brief Layer state compare | ||
| 127 | * | ||
| 128 | * Used for comparing layers {mostly used for unit testing} | ||
| 129 | */ | ||
| 130 | bool layer_state_cmp(layer_state_t cmp_layer_state, uint8_t layer) { | ||
| 131 | if (!cmp_layer_state) { | ||
| 132 | return layer == 0; | ||
| 133 | } | ||
| 134 | return (cmp_layer_state & (1UL << layer)) != 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | /** \brief Layer move | ||
| 138 | * | ||
| 139 | * Turns on the given layer and turn off all other layers | ||
| 140 | */ | ||
| 141 | void layer_move(uint8_t layer) { layer_state_set(1UL << layer); } | ||
| 142 | |||
| 143 | /** \brief Layer on | ||
| 144 | * | ||
| 145 | * Turns on given layer | ||
| 146 | */ | ||
| 147 | void layer_on(uint8_t layer) { layer_state_set(layer_state | (1UL << layer)); } | ||
| 148 | |||
| 149 | /** \brief Layer off | ||
| 150 | * | ||
| 151 | * Turns off given layer | ||
| 152 | */ | ||
| 153 | void layer_off(uint8_t layer) { layer_state_set(layer_state & ~(1UL << layer)); } | ||
| 154 | |||
| 155 | /** \brief Layer invert | ||
| 156 | * | ||
| 157 | * Toggle the given layer (set it if it's unset, or unset it if it's set) | ||
| 158 | */ | ||
| 159 | void layer_invert(uint8_t layer) { layer_state_set(layer_state ^ (1UL << layer)); } | ||
| 160 | |||
| 161 | /** \brief Layer or | ||
| 162 | * | ||
| 163 | * Turns on layers based on matching bits between specifed layer and existing layer state | ||
| 164 | */ | ||
| 165 | void layer_or(layer_state_t state) { layer_state_set(layer_state | state); } | ||
| 166 | /** \brief Layer and | ||
| 167 | * | ||
| 168 | * Turns on layers based on matching enabled bits between specifed layer and existing layer state | ||
| 169 | */ | ||
| 170 | void layer_and(layer_state_t state) { layer_state_set(layer_state & state); } | ||
| 171 | /** \brief Layer xor | ||
| 172 | * | ||
| 173 | * Turns on layers based on non-matching bits between specifed layer and existing layer state | ||
| 174 | */ | ||
| 175 | void layer_xor(layer_state_t state) { layer_state_set(layer_state ^ state); } | ||
| 176 | |||
| 177 | /** \brief Layer debug printing | ||
| 178 | * | ||
| 179 | * Print out the hex value of the 32-bit layer state, as well as the value of the highest bit. | ||
| 180 | */ | ||
| 181 | void layer_debug(void) { dprintf("%08lX(%u)", layer_state, get_highest_layer(layer_state)); } | ||
| 182 | #endif | ||
| 183 | |||
| 184 | #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) | ||
| 185 | /** \brief source layer cache | ||
| 186 | */ | ||
| 187 | |||
| 188 | uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}}; | ||
| 189 | |||
| 190 | /** \brief update source layers cache | ||
| 191 | * | ||
| 192 | * Updates the cached keys when changing layers | ||
| 193 | */ | ||
| 194 | void update_source_layers_cache(keypos_t key, uint8_t layer) { | ||
| 195 | const uint8_t key_number = key.col + (key.row * MATRIX_COLS); | ||
| 196 | const uint8_t storage_row = key_number / 8; | ||
| 197 | const uint8_t storage_bit = key_number % 8; | ||
| 198 | |||
| 199 | for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) { | ||
| 200 | source_layers_cache[storage_row][bit_number] ^= (-((layer & (1U << bit_number)) != 0) ^ source_layers_cache[storage_row][bit_number]) & (1U << storage_bit); | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | /** \brief read source layers cache | ||
| 205 | * | ||
| 206 | * reads the cached keys stored when the layer was changed | ||
| 207 | */ | ||
| 208 | uint8_t read_source_layers_cache(keypos_t key) { | ||
| 209 | const uint8_t key_number = key.col + (key.row * MATRIX_COLS); | ||
| 210 | const uint8_t storage_row = key_number / 8; | ||
| 211 | const uint8_t storage_bit = key_number % 8; | ||
| 212 | uint8_t layer = 0; | ||
| 213 | |||
| 214 | for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) { | ||
| 215 | layer |= ((source_layers_cache[storage_row][bit_number] & (1U << storage_bit)) != 0) << bit_number; | ||
| 216 | } | ||
| 217 | |||
| 218 | return layer; | ||
| 219 | } | ||
| 220 | #endif | ||
| 221 | |||
| 222 | /** \brief Store or get action (FIXME: Needs better summary) | ||
| 223 | * | ||
| 224 | * Make sure the action triggered when the key is released is the same | ||
| 225 | * one as the one triggered on press. It's important for the mod keys | ||
| 226 | * when the layer is switched after the down event but before the up | ||
| 227 | * event as they may get stuck otherwise. | ||
| 228 | */ | ||
| 229 | action_t store_or_get_action(bool pressed, keypos_t key) { | ||
| 230 | #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) | ||
| 231 | if (disable_action_cache) { | ||
| 232 | return layer_switch_get_action(key); | ||
| 233 | } | ||
| 234 | |||
| 235 | uint8_t layer; | ||
| 236 | |||
| 237 | if (pressed) { | ||
| 238 | layer = layer_switch_get_layer(key); | ||
| 239 | update_source_layers_cache(key, layer); | ||
| 240 | } else { | ||
| 241 | layer = read_source_layers_cache(key); | ||
| 242 | } | ||
| 243 | return action_for_key(layer, key); | ||
| 244 | #else | ||
| 245 | return layer_switch_get_action(key); | ||
| 246 | #endif | ||
| 247 | } | ||
| 248 | |||
| 249 | /** \brief Layer switch get layer | ||
| 250 | * | ||
| 251 | * Gets the layer based on key info | ||
| 252 | */ | ||
| 253 | uint8_t layer_switch_get_layer(keypos_t key) { | ||
| 254 | #ifndef NO_ACTION_LAYER | ||
| 255 | action_t action; | ||
| 256 | action.code = ACTION_TRANSPARENT; | ||
| 257 | |||
| 258 | layer_state_t layers = layer_state | default_layer_state; | ||
| 259 | /* check top layer first */ | ||
| 260 | for (int8_t i = MAX_LAYER - 1; i >= 0; i--) { | ||
| 261 | if (layers & (1UL << i)) { | ||
| 262 | action = action_for_key(i, key); | ||
| 263 | if (action.code != ACTION_TRANSPARENT) { | ||
| 264 | return i; | ||
| 265 | } | ||
| 266 | } | ||
| 267 | } | ||
| 268 | /* fall back to layer 0 */ | ||
| 269 | return 0; | ||
| 270 | #else | ||
| 271 | return get_highest_layer(default_layer_state); | ||
| 272 | #endif | ||
| 273 | } | ||
| 274 | |||
| 275 | /** \brief Layer switch get layer | ||
| 276 | * | ||
| 277 | * Gets action code based on key position | ||
| 278 | */ | ||
| 279 | action_t layer_switch_get_action(keypos_t key) { return action_for_key(layer_switch_get_layer(key), key); } | ||
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h deleted file mode 100644 index d72cd3e3a..000000000 --- a/tmk_core/common/action_layer.h +++ /dev/null | |||
| @@ -1,122 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <stdint.h> | ||
| 21 | #include "keyboard.h" | ||
| 22 | #include "action.h" | ||
| 23 | |||
| 24 | #if defined(LAYER_STATE_8BIT) | ||
| 25 | typedef uint8_t layer_state_t; | ||
| 26 | # define MAX_LAYER_BITS 3 | ||
| 27 | # ifndef MAX_LAYER | ||
| 28 | # define MAX_LAYER 8 | ||
| 29 | # endif | ||
| 30 | # define get_highest_layer(state) biton(state) | ||
| 31 | #elif defined(LAYER_STATE_16BIT) | ||
| 32 | typedef uint16_t layer_state_t; | ||
| 33 | # define MAX_LAYER_BITS 4 | ||
| 34 | # ifndef MAX_LAYER | ||
| 35 | # define MAX_LAYER 16 | ||
| 36 | # endif | ||
| 37 | # define get_highest_layer(state) biton16(state) | ||
| 38 | #else | ||
| 39 | typedef uint32_t layer_state_t; | ||
| 40 | # define MAX_LAYER_BITS 5 | ||
| 41 | # ifndef MAX_LAYER | ||
| 42 | # define MAX_LAYER 32 | ||
| 43 | # endif | ||
| 44 | # define get_highest_layer(state) biton32(state) | ||
| 45 | #endif | ||
| 46 | |||
| 47 | /* | ||
| 48 | * Default Layer | ||
| 49 | */ | ||
| 50 | extern layer_state_t default_layer_state; | ||
| 51 | void default_layer_debug(void); | ||
| 52 | void default_layer_set(layer_state_t state); | ||
| 53 | |||
| 54 | __attribute__((weak)) layer_state_t default_layer_state_set_kb(layer_state_t state); | ||
| 55 | __attribute__((weak)) layer_state_t default_layer_state_set_user(layer_state_t state); | ||
| 56 | |||
| 57 | #ifndef NO_ACTION_LAYER | ||
| 58 | /* bitwise operation */ | ||
| 59 | void default_layer_or(layer_state_t state); | ||
| 60 | void default_layer_and(layer_state_t state); | ||
| 61 | void default_layer_xor(layer_state_t state); | ||
| 62 | #else | ||
| 63 | # define default_layer_or(state) | ||
| 64 | # define default_layer_and(state) | ||
| 65 | # define default_layer_xor(state) | ||
| 66 | #endif | ||
| 67 | |||
| 68 | /* | ||
| 69 | * Keymap Layer | ||
| 70 | */ | ||
| 71 | #ifndef NO_ACTION_LAYER | ||
| 72 | extern layer_state_t layer_state; | ||
| 73 | |||
| 74 | void layer_state_set(layer_state_t state); | ||
| 75 | bool layer_state_is(uint8_t layer); | ||
| 76 | bool layer_state_cmp(layer_state_t layer1, uint8_t layer2); | ||
| 77 | |||
| 78 | void layer_debug(void); | ||
| 79 | void layer_clear(void); | ||
| 80 | void layer_move(uint8_t layer); | ||
| 81 | void layer_on(uint8_t layer); | ||
| 82 | void layer_off(uint8_t layer); | ||
| 83 | void layer_invert(uint8_t layer); | ||
| 84 | /* bitwise operation */ | ||
| 85 | void layer_or(layer_state_t state); | ||
| 86 | void layer_and(layer_state_t state); | ||
| 87 | void layer_xor(layer_state_t state); | ||
| 88 | layer_state_t layer_state_set_user(layer_state_t state); | ||
| 89 | layer_state_t layer_state_set_kb(layer_state_t state); | ||
| 90 | #else | ||
| 91 | # define layer_state 0 | ||
| 92 | |||
| 93 | # define layer_state_set(layer) | ||
| 94 | # define layer_state_is(layer) (layer == 0) | ||
| 95 | # define layer_state_cmp(state, layer) (state == 0 ? layer == 0 : (state & 1UL << layer) != 0) | ||
| 96 | |||
| 97 | # define layer_debug() | ||
| 98 | # define layer_clear() | ||
| 99 | # define layer_move(layer) (void)layer | ||
| 100 | # define layer_on(layer) (void)layer | ||
| 101 | # define layer_off(layer) (void)layer | ||
| 102 | # define layer_invert(layer) (void)layer | ||
| 103 | # define layer_or(state) (void)state | ||
| 104 | # define layer_and(state) (void)state | ||
| 105 | # define layer_xor(state) (void)state | ||
| 106 | # define layer_state_set_kb(state) (void)state | ||
| 107 | # define layer_state_set_user(state) (void)state | ||
| 108 | #endif | ||
| 109 | |||
| 110 | /* pressed actions cache */ | ||
| 111 | #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) | ||
| 112 | |||
| 113 | void update_source_layers_cache(keypos_t key, uint8_t layer); | ||
| 114 | uint8_t read_source_layers_cache(keypos_t key); | ||
| 115 | #endif | ||
| 116 | action_t store_or_get_action(bool pressed, keypos_t key); | ||
| 117 | |||
| 118 | /* return the topmost non-transparent layer currently associated with key */ | ||
| 119 | uint8_t layer_switch_get_layer(keypos_t key); | ||
| 120 | |||
| 121 | /* return action depending on current layer status */ | ||
| 122 | action_t layer_switch_get_action(keypos_t key); | ||
diff --git a/tmk_core/common/action_macro.c b/tmk_core/common/action_macro.c deleted file mode 100644 index 92228c0ba..000000000 --- a/tmk_core/common/action_macro.c +++ /dev/null | |||
| @@ -1,93 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | #include "action.h" | ||
| 18 | #include "action_util.h" | ||
| 19 | #include "action_macro.h" | ||
| 20 | #include "wait.h" | ||
| 21 | |||
| 22 | #ifdef DEBUG_ACTION | ||
| 23 | # include "debug.h" | ||
| 24 | #else | ||
| 25 | # include "nodebug.h" | ||
| 26 | #endif | ||
| 27 | |||
| 28 | #ifndef NO_ACTION_MACRO | ||
| 29 | |||
| 30 | # define MACRO_READ() (macro = MACRO_GET(macro_p++)) | ||
| 31 | /** \brief Action Macro Play | ||
| 32 | * | ||
| 33 | * FIXME: Needs doc | ||
| 34 | */ | ||
| 35 | void action_macro_play(const macro_t *macro_p) { | ||
| 36 | macro_t macro = END; | ||
| 37 | uint8_t interval = 0; | ||
| 38 | |||
| 39 | if (!macro_p) return; | ||
| 40 | while (true) { | ||
| 41 | switch (MACRO_READ()) { | ||
| 42 | case KEY_DOWN: | ||
| 43 | MACRO_READ(); | ||
| 44 | dprintf("KEY_DOWN(%02X)\n", macro); | ||
| 45 | if (IS_MOD(macro)) { | ||
| 46 | add_macro_mods(MOD_BIT(macro)); | ||
| 47 | send_keyboard_report(); | ||
| 48 | } else { | ||
| 49 | register_code(macro); | ||
| 50 | } | ||
| 51 | break; | ||
| 52 | case KEY_UP: | ||
| 53 | MACRO_READ(); | ||
| 54 | dprintf("KEY_UP(%02X)\n", macro); | ||
| 55 | if (IS_MOD(macro)) { | ||
| 56 | del_macro_mods(MOD_BIT(macro)); | ||
| 57 | send_keyboard_report(); | ||
| 58 | } else { | ||
| 59 | unregister_code(macro); | ||
| 60 | } | ||
| 61 | break; | ||
| 62 | case WAIT: | ||
| 63 | MACRO_READ(); | ||
| 64 | dprintf("WAIT(%u)\n", macro); | ||
| 65 | { | ||
| 66 | uint8_t ms = macro; | ||
| 67 | while (ms--) wait_ms(1); | ||
| 68 | } | ||
| 69 | break; | ||
| 70 | case INTERVAL: | ||
| 71 | interval = MACRO_READ(); | ||
| 72 | dprintf("INTERVAL(%u)\n", interval); | ||
| 73 | break; | ||
| 74 | case 0x04 ... 0x73: | ||
| 75 | dprintf("DOWN(%02X)\n", macro); | ||
| 76 | register_code(macro); | ||
| 77 | break; | ||
| 78 | case 0x84 ... 0xF3: | ||
| 79 | dprintf("UP(%02X)\n", macro); | ||
| 80 | unregister_code(macro & 0x7F); | ||
| 81 | break; | ||
| 82 | case END: | ||
| 83 | default: | ||
| 84 | return; | ||
| 85 | } | ||
| 86 | // interval | ||
| 87 | { | ||
| 88 | uint8_t ms = interval; | ||
| 89 | while (ms--) wait_ms(1); | ||
| 90 | } | ||
| 91 | } | ||
| 92 | } | ||
| 93 | #endif | ||
diff --git a/tmk_core/common/action_macro.h b/tmk_core/common/action_macro.h deleted file mode 100644 index 685e2c6ff..000000000 --- a/tmk_core/common/action_macro.h +++ /dev/null | |||
| @@ -1,123 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <stdint.h> | ||
| 21 | #include "progmem.h" | ||
| 22 | |||
| 23 | typedef uint8_t macro_t; | ||
| 24 | |||
| 25 | #define MACRO_NONE (macro_t *)0 | ||
| 26 | #define MACRO(...) \ | ||
| 27 | ({ \ | ||
| 28 | static const macro_t __m[] PROGMEM = {__VA_ARGS__}; \ | ||
| 29 | &__m[0]; \ | ||
| 30 | }) | ||
| 31 | #define MACRO_GET(p) pgm_read_byte(p) | ||
| 32 | |||
| 33 | // Sends press when the macro key is pressed, release when release, or tap_macro when the key has been tapped | ||
| 34 | #define MACRO_TAP_HOLD(record, press, release, tap_macro) (((record)->event.pressed) ? (((record)->tap.count <= 0 || (record)->tap.interrupted) ? (press) : MACRO_NONE) : (((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (tap_macro) : (release))) | ||
| 35 | |||
| 36 | // Holds down the modifier mod when the macro key is held, or sends macro instead when tapped | ||
| 37 | #define MACRO_TAP_HOLD_MOD(record, macro, mod) MACRO_TAP_HOLD(record, (MACRO(D(mod), END)), MACRO(U(mod), END), macro) | ||
| 38 | |||
| 39 | // Holds down the modifier mod when the macro key is held, or pressed a shifted key when tapped (eg: shift+3 for #) | ||
| 40 | #define MACRO_TAP_SHFT_KEY_HOLD_MOD(record, key, mod) MACRO_TAP_HOLD_MOD(record, (MACRO(I(10), D(LSFT), T(key), U(LSFT), END)), mod) | ||
| 41 | |||
| 42 | // Momentary switch layer when held, sends macro if tapped | ||
| 43 | #define MACRO_TAP_HOLD_LAYER(record, macro, layer) \ | ||
| 44 | (((record)->event.pressed) ? (((record)->tap.count <= 0 || (record)->tap.interrupted) ? ({ \ | ||
| 45 | layer_on((layer)); \ | ||
| 46 | MACRO_NONE; \ | ||
| 47 | }) \ | ||
| 48 | : MACRO_NONE) \ | ||
| 49 | : (((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (macro) : ({ \ | ||
| 50 | layer_off((layer)); \ | ||
| 51 | MACRO_NONE; \ | ||
| 52 | }))) | ||
| 53 | |||
| 54 | // Momentary switch layer when held, presses a shifted key when tapped (eg: shift+3 for #) | ||
| 55 | #define MACRO_TAP_SHFT_KEY_HOLD_LAYER(record, key, layer) MACRO_TAP_HOLD_LAYER(record, MACRO(I(10), D(LSFT), T(key), U(LSFT), END), layer) | ||
| 56 | |||
| 57 | #ifndef NO_ACTION_MACRO | ||
| 58 | void action_macro_play(const macro_t *macro_p); | ||
| 59 | #else | ||
| 60 | # define action_macro_play(macro) | ||
| 61 | #endif | ||
| 62 | |||
| 63 | /* Macro commands | ||
| 64 | * code(0x04-73) // key down(1byte) | ||
| 65 | * code(0x04-73) | 0x80 // key up(1byte) | ||
| 66 | * { KEY_DOWN, code(0x04-0xff) } // key down(2bytes) | ||
| 67 | * { KEY_UP, code(0x04-0xff) } // key up(2bytes) | ||
| 68 | * WAIT // wait milli-seconds | ||
| 69 | * INTERVAL // set interval between macro commands | ||
| 70 | * END // stop macro execution | ||
| 71 | * | ||
| 72 | * Ideas(Not implemented): | ||
| 73 | * modifiers | ||
| 74 | * system usage | ||
| 75 | * consumer usage | ||
| 76 | * unicode usage | ||
| 77 | * function call | ||
| 78 | * conditionals | ||
| 79 | * loop | ||
| 80 | */ | ||
| 81 | enum macro_command_id { | ||
| 82 | /* 0x00 - 0x03 */ | ||
| 83 | END = 0x00, | ||
| 84 | KEY_DOWN, | ||
| 85 | KEY_UP, | ||
| 86 | |||
| 87 | /* 0x04 - 0x73 (reserved for keycode down) */ | ||
| 88 | |||
| 89 | /* 0x74 - 0x83 */ | ||
| 90 | WAIT = 0x74, | ||
| 91 | INTERVAL, | ||
| 92 | |||
| 93 | /* 0x84 - 0xf3 (reserved for keycode up) */ | ||
| 94 | |||
| 95 | /* 0xf4 - 0xff */ | ||
| 96 | }; | ||
| 97 | |||
| 98 | /* TODO: keycode:0x04-0x73 can be handled by 1byte command else 2bytes are needed | ||
| 99 | * if keycode between 0x04 and 0x73 | ||
| 100 | * keycode / (keycode|0x80) | ||
| 101 | * else | ||
| 102 | * {KEY_DOWN, keycode} / {KEY_UP, keycode} | ||
| 103 | */ | ||
| 104 | #define DOWN(key) KEY_DOWN, (key) | ||
| 105 | #define UP(key) KEY_UP, (key) | ||
| 106 | #define TYPE(key) DOWN(key), UP(key) | ||
| 107 | #define WAIT(ms) WAIT, (ms) | ||
| 108 | #define INTERVAL(ms) INTERVAL, (ms) | ||
| 109 | |||
| 110 | /* key down */ | ||
| 111 | #define D(key) DOWN(KC_##key) | ||
| 112 | /* key up */ | ||
| 113 | #define U(key) UP(KC_##key) | ||
| 114 | /* key type */ | ||
| 115 | #define T(key) TYPE(KC_##key) | ||
| 116 | /* wait */ | ||
| 117 | #define W(ms) WAIT(ms) | ||
| 118 | /* interval */ | ||
| 119 | #define I(ms) INTERVAL(ms) | ||
| 120 | |||
| 121 | /* for backward comaptibility */ | ||
| 122 | #define MD(key) DOWN(KC_##key) | ||
| 123 | #define MU(key) UP(KC_##key) | ||
diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c deleted file mode 100644 index 56044e096..000000000 --- a/tmk_core/common/action_tapping.c +++ /dev/null | |||
| @@ -1,426 +0,0 @@ | |||
| 1 | #include <stdint.h> | ||
| 2 | #include <stdbool.h> | ||
| 3 | #include "action.h" | ||
| 4 | #include "action_layer.h" | ||
| 5 | #include "action_tapping.h" | ||
| 6 | #include "keycode.h" | ||
| 7 | #include "timer.h" | ||
| 8 | |||
| 9 | #ifdef DEBUG_ACTION | ||
| 10 | # include "debug.h" | ||
| 11 | #else | ||
| 12 | # include "nodebug.h" | ||
| 13 | #endif | ||
| 14 | |||
| 15 | #ifndef NO_ACTION_TAPPING | ||
| 16 | |||
| 17 | # define IS_TAPPING() !IS_NOEVENT(tapping_key.event) | ||
| 18 | # define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed) | ||
| 19 | # define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed) | ||
| 20 | # define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k))) | ||
| 21 | |||
| 22 | __attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { return TAPPING_TERM; } | ||
| 23 | |||
| 24 | # ifdef TAPPING_TERM_PER_KEY | ||
| 25 | # define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_event_keycode(tapping_key.event, false), &tapping_key)) | ||
| 26 | # else | ||
| 27 | # define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM) | ||
| 28 | # endif | ||
| 29 | |||
| 30 | # ifdef TAPPING_FORCE_HOLD_PER_KEY | ||
| 31 | __attribute__((weak)) bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record) { return false; } | ||
| 32 | # endif | ||
| 33 | |||
| 34 | # ifdef PERMISSIVE_HOLD_PER_KEY | ||
| 35 | __attribute__((weak)) bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) { return false; } | ||
| 36 | # endif | ||
| 37 | |||
| 38 | static keyrecord_t tapping_key = {}; | ||
| 39 | static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {}; | ||
| 40 | static uint8_t waiting_buffer_head = 0; | ||
| 41 | static uint8_t waiting_buffer_tail = 0; | ||
| 42 | |||
| 43 | static bool process_tapping(keyrecord_t *record); | ||
| 44 | static bool waiting_buffer_enq(keyrecord_t record); | ||
| 45 | static void waiting_buffer_clear(void); | ||
| 46 | static bool waiting_buffer_typed(keyevent_t event); | ||
| 47 | static bool waiting_buffer_has_anykey_pressed(void); | ||
| 48 | static void waiting_buffer_scan_tap(void); | ||
| 49 | static void debug_tapping_key(void); | ||
| 50 | static void debug_waiting_buffer(void); | ||
| 51 | |||
| 52 | /** \brief Action Tapping Process | ||
| 53 | * | ||
| 54 | * FIXME: Needs doc | ||
| 55 | */ | ||
| 56 | void action_tapping_process(keyrecord_t record) { | ||
| 57 | if (process_tapping(&record)) { | ||
| 58 | if (!IS_NOEVENT(record.event)) { | ||
| 59 | debug("processed: "); | ||
| 60 | debug_record(record); | ||
| 61 | debug("\n"); | ||
| 62 | } | ||
| 63 | } else { | ||
| 64 | if (!waiting_buffer_enq(record)) { | ||
| 65 | // clear all in case of overflow. | ||
| 66 | debug("OVERFLOW: CLEAR ALL STATES\n"); | ||
| 67 | clear_keyboard(); | ||
| 68 | waiting_buffer_clear(); | ||
| 69 | tapping_key = (keyrecord_t){}; | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | // process waiting_buffer | ||
| 74 | if (!IS_NOEVENT(record.event) && waiting_buffer_head != waiting_buffer_tail) { | ||
| 75 | debug("---- action_exec: process waiting_buffer -----\n"); | ||
| 76 | } | ||
| 77 | for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) { | ||
| 78 | if (process_tapping(&waiting_buffer[waiting_buffer_tail])) { | ||
| 79 | debug("processed: waiting_buffer["); | ||
| 80 | debug_dec(waiting_buffer_tail); | ||
| 81 | debug("] = "); | ||
| 82 | debug_record(waiting_buffer[waiting_buffer_tail]); | ||
| 83 | debug("\n\n"); | ||
| 84 | } else { | ||
| 85 | break; | ||
| 86 | } | ||
| 87 | } | ||
| 88 | if (!IS_NOEVENT(record.event)) { | ||
| 89 | debug("\n"); | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | /** \brief Tapping | ||
| 94 | * | ||
| 95 | * Rule: Tap key is typed(pressed and released) within TAPPING_TERM. | ||
| 96 | * (without interfering by typing other key) | ||
| 97 | */ | ||
| 98 | /* return true when key event is processed or consumed. */ | ||
| 99 | bool process_tapping(keyrecord_t *keyp) { | ||
| 100 | keyevent_t event = keyp->event; | ||
| 101 | |||
| 102 | // if tapping | ||
| 103 | if (IS_TAPPING_PRESSED()) { | ||
| 104 | if (WITHIN_TAPPING_TERM(event)) { | ||
| 105 | if (tapping_key.tap.count == 0) { | ||
| 106 | if (IS_TAPPING_KEY(event.key) && !event.pressed) { | ||
| 107 | // first tap! | ||
| 108 | debug("Tapping: First tap(0->1).\n"); | ||
| 109 | tapping_key.tap.count = 1; | ||
| 110 | debug_tapping_key(); | ||
| 111 | process_record(&tapping_key); | ||
| 112 | |||
| 113 | // copy tapping state | ||
| 114 | keyp->tap = tapping_key.tap; | ||
| 115 | // enqueue | ||
| 116 | return false; | ||
| 117 | } | ||
| 118 | /* Process a key typed within TAPPING_TERM | ||
| 119 | * This can register the key before settlement of tapping, | ||
| 120 | * useful for long TAPPING_TERM but may prevent fast typing. | ||
| 121 | */ | ||
| 122 | # if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY) | ||
| 123 | else if ((( | ||
| 124 | # ifdef TAPPING_TERM_PER_KEY | ||
| 125 | get_tapping_term(get_event_keycode(tapping_key.event, false), keyp) | ||
| 126 | # else | ||
| 127 | TAPPING_TERM | ||
| 128 | # endif | ||
| 129 | >= 500) | ||
| 130 | |||
| 131 | # ifdef PERMISSIVE_HOLD_PER_KEY | ||
| 132 | || get_permissive_hold(get_event_keycode(tapping_key.event, false), keyp) | ||
| 133 | # elif defined(PERMISSIVE_HOLD) | ||
| 134 | || true | ||
| 135 | # endif | ||
| 136 | ) && | ||
| 137 | IS_RELEASED(event) && waiting_buffer_typed(event)) { | ||
| 138 | debug("Tapping: End. No tap. Interfered by typing key\n"); | ||
| 139 | process_record(&tapping_key); | ||
| 140 | tapping_key = (keyrecord_t){}; | ||
| 141 | debug_tapping_key(); | ||
| 142 | // enqueue | ||
| 143 | return false; | ||
| 144 | } | ||
| 145 | # endif | ||
| 146 | /* Process release event of a key pressed before tapping starts | ||
| 147 | * Without this unexpected repeating will occur with having fast repeating setting | ||
| 148 | * https://github.com/tmk/tmk_keyboard/issues/60 | ||
| 149 | */ | ||
| 150 | else if (IS_RELEASED(event) && !waiting_buffer_typed(event)) { | ||
| 151 | // Modifier should be retained till end of this tapping. | ||
| 152 | action_t action = layer_switch_get_action(event.key); | ||
| 153 | switch (action.kind.id) { | ||
| 154 | case ACT_LMODS: | ||
| 155 | case ACT_RMODS: | ||
| 156 | if (action.key.mods && !action.key.code) return false; | ||
| 157 | if (IS_MOD(action.key.code)) return false; | ||
| 158 | break; | ||
| 159 | case ACT_LMODS_TAP: | ||
| 160 | case ACT_RMODS_TAP: | ||
| 161 | if (action.key.mods && keyp->tap.count == 0) return false; | ||
| 162 | if (IS_MOD(action.key.code)) return false; | ||
| 163 | break; | ||
| 164 | } | ||
| 165 | // Release of key should be process immediately. | ||
| 166 | debug("Tapping: release event of a key pressed before tapping\n"); | ||
| 167 | process_record(keyp); | ||
| 168 | return true; | ||
| 169 | } else { | ||
| 170 | // set interrupted flag when other key preesed during tapping | ||
| 171 | if (event.pressed) { | ||
| 172 | tapping_key.tap.interrupted = true; | ||
| 173 | } | ||
| 174 | // enqueue | ||
| 175 | return false; | ||
| 176 | } | ||
| 177 | } | ||
| 178 | // tap_count > 0 | ||
| 179 | else { | ||
| 180 | if (IS_TAPPING_KEY(event.key) && !event.pressed) { | ||
| 181 | debug("Tapping: Tap release("); | ||
| 182 | debug_dec(tapping_key.tap.count); | ||
| 183 | debug(")\n"); | ||
| 184 | keyp->tap = tapping_key.tap; | ||
| 185 | process_record(keyp); | ||
| 186 | tapping_key = *keyp; | ||
| 187 | debug_tapping_key(); | ||
| 188 | return true; | ||
| 189 | } else if (is_tap_key(event.key) && event.pressed) { | ||
| 190 | if (tapping_key.tap.count > 1) { | ||
| 191 | debug("Tapping: Start new tap with releasing last tap(>1).\n"); | ||
| 192 | // unregister key | ||
| 193 | process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false}); | ||
| 194 | } else { | ||
| 195 | debug("Tapping: Start while last tap(1).\n"); | ||
| 196 | } | ||
| 197 | tapping_key = *keyp; | ||
| 198 | waiting_buffer_scan_tap(); | ||
| 199 | debug_tapping_key(); | ||
| 200 | return true; | ||
| 201 | } else { | ||
| 202 | if (!IS_NOEVENT(event)) { | ||
| 203 | debug("Tapping: key event while last tap(>0).\n"); | ||
| 204 | } | ||
| 205 | process_record(keyp); | ||
| 206 | return true; | ||
| 207 | } | ||
| 208 | } | ||
| 209 | } | ||
| 210 | // after TAPPING_TERM | ||
| 211 | else { | ||
| 212 | if (tapping_key.tap.count == 0) { | ||
| 213 | debug("Tapping: End. Timeout. Not tap(0): "); | ||
| 214 | debug_event(event); | ||
| 215 | debug("\n"); | ||
| 216 | process_record(&tapping_key); | ||
| 217 | tapping_key = (keyrecord_t){}; | ||
| 218 | debug_tapping_key(); | ||
| 219 | return false; | ||
| 220 | } else { | ||
| 221 | if (IS_TAPPING_KEY(event.key) && !event.pressed) { | ||
| 222 | debug("Tapping: End. last timeout tap release(>0)."); | ||
| 223 | keyp->tap = tapping_key.tap; | ||
| 224 | process_record(keyp); | ||
| 225 | tapping_key = (keyrecord_t){}; | ||
| 226 | return true; | ||
| 227 | } else if (is_tap_key(event.key) && event.pressed) { | ||
| 228 | if (tapping_key.tap.count > 1) { | ||
| 229 | debug("Tapping: Start new tap with releasing last timeout tap(>1).\n"); | ||
| 230 | // unregister key | ||
| 231 | process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false}); | ||
| 232 | } else { | ||
| 233 | debug("Tapping: Start while last timeout tap(1).\n"); | ||
| 234 | } | ||
| 235 | tapping_key = *keyp; | ||
| 236 | waiting_buffer_scan_tap(); | ||
| 237 | debug_tapping_key(); | ||
| 238 | return true; | ||
| 239 | } else { | ||
| 240 | if (!IS_NOEVENT(event)) { | ||
| 241 | debug("Tapping: key event while last timeout tap(>0).\n"); | ||
| 242 | } | ||
| 243 | process_record(keyp); | ||
| 244 | return true; | ||
| 245 | } | ||
| 246 | } | ||
| 247 | } | ||
| 248 | } else if (IS_TAPPING_RELEASED()) { | ||
| 249 | if (WITHIN_TAPPING_TERM(event)) { | ||
| 250 | if (event.pressed) { | ||
| 251 | if (IS_TAPPING_KEY(event.key)) { | ||
| 252 | //# ifndef TAPPING_FORCE_HOLD | ||
| 253 | # if !defined(TAPPING_FORCE_HOLD) || defined(TAPPING_FORCE_HOLD_PER_KEY) | ||
| 254 | if ( | ||
| 255 | # ifdef TAPPING_FORCE_HOLD_PER_KEY | ||
| 256 | !get_tapping_force_hold(get_event_keycode(tapping_key.event, false), keyp) && | ||
| 257 | # endif | ||
| 258 | !tapping_key.tap.interrupted && tapping_key.tap.count > 0) { | ||
| 259 | // sequential tap. | ||
| 260 | keyp->tap = tapping_key.tap; | ||
| 261 | if (keyp->tap.count < 15) keyp->tap.count += 1; | ||
| 262 | debug("Tapping: Tap press("); | ||
| 263 | debug_dec(keyp->tap.count); | ||
| 264 | debug(")\n"); | ||
| 265 | process_record(keyp); | ||
| 266 | tapping_key = *keyp; | ||
| 267 | debug_tapping_key(); | ||
| 268 | return true; | ||
| 269 | } | ||
| 270 | # endif | ||
| 271 | // FIX: start new tap again | ||
| 272 | tapping_key = *keyp; | ||
| 273 | return true; | ||
| 274 | } else if (is_tap_key(event.key)) { | ||
| 275 | // Sequential tap can be interfered with other tap key. | ||
| 276 | debug("Tapping: Start with interfering other tap.\n"); | ||
| 277 | tapping_key = *keyp; | ||
| 278 | waiting_buffer_scan_tap(); | ||
| 279 | debug_tapping_key(); | ||
| 280 | return true; | ||
| 281 | } else { | ||
| 282 | // should none in buffer | ||
| 283 | // FIX: interrupted when other key is pressed | ||
| 284 | tapping_key.tap.interrupted = true; | ||
| 285 | process_record(keyp); | ||
| 286 | return true; | ||
| 287 | } | ||
| 288 | } else { | ||
| 289 | if (!IS_NOEVENT(event)) debug("Tapping: other key just after tap.\n"); | ||
| 290 | process_record(keyp); | ||
| 291 | return true; | ||
| 292 | } | ||
| 293 | } else { | ||
| 294 | // FIX: process_action here? | ||
| 295 | // timeout. no sequential tap. | ||
| 296 | debug("Tapping: End(Timeout after releasing last tap): "); | ||
| 297 | debug_event(event); | ||
| 298 | debug("\n"); | ||
| 299 | tapping_key = (keyrecord_t){}; | ||
| 300 | debug_tapping_key(); | ||
| 301 | return false; | ||
| 302 | } | ||
| 303 | } | ||
| 304 | // not tapping state | ||
| 305 | else { | ||
| 306 | if (event.pressed && is_tap_key(event.key)) { | ||
| 307 | debug("Tapping: Start(Press tap key).\n"); | ||
| 308 | tapping_key = *keyp; | ||
| 309 | process_record_tap_hint(&tapping_key); | ||
| 310 | waiting_buffer_scan_tap(); | ||
| 311 | debug_tapping_key(); | ||
| 312 | return true; | ||
| 313 | } else { | ||
| 314 | process_record(keyp); | ||
| 315 | return true; | ||
| 316 | } | ||
| 317 | } | ||
| 318 | } | ||
| 319 | |||
| 320 | /** \brief Waiting buffer enq | ||
| 321 | * | ||
| 322 | * FIXME: Needs docs | ||
| 323 | */ | ||
| 324 | bool waiting_buffer_enq(keyrecord_t record) { | ||
| 325 | if (IS_NOEVENT(record.event)) { | ||
| 326 | return true; | ||
| 327 | } | ||
| 328 | |||
| 329 | if ((waiting_buffer_head + 1) % WAITING_BUFFER_SIZE == waiting_buffer_tail) { | ||
| 330 | debug("waiting_buffer_enq: Over flow.\n"); | ||
| 331 | return false; | ||
| 332 | } | ||
| 333 | |||
| 334 | waiting_buffer[waiting_buffer_head] = record; | ||
| 335 | waiting_buffer_head = (waiting_buffer_head + 1) % WAITING_BUFFER_SIZE; | ||
| 336 | |||
| 337 | debug("waiting_buffer_enq: "); | ||
| 338 | debug_waiting_buffer(); | ||
| 339 | return true; | ||
| 340 | } | ||
| 341 | |||
| 342 | /** \brief Waiting buffer clear | ||
| 343 | * | ||
| 344 | * FIXME: Needs docs | ||
| 345 | */ | ||
| 346 | void waiting_buffer_clear(void) { | ||
| 347 | waiting_buffer_head = 0; | ||
| 348 | waiting_buffer_tail = 0; | ||
| 349 | } | ||
| 350 | |||
| 351 | /** \brief Waiting buffer typed | ||
| 352 | * | ||
| 353 | * FIXME: Needs docs | ||
| 354 | */ | ||
| 355 | bool waiting_buffer_typed(keyevent_t event) { | ||
| 356 | for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { | ||
| 357 | if (KEYEQ(event.key, waiting_buffer[i].event.key) && event.pressed != waiting_buffer[i].event.pressed) { | ||
| 358 | return true; | ||
| 359 | } | ||
| 360 | } | ||
| 361 | return false; | ||
| 362 | } | ||
| 363 | |||
| 364 | /** \brief Waiting buffer has anykey pressed | ||
| 365 | * | ||
| 366 | * FIXME: Needs docs | ||
| 367 | */ | ||
| 368 | __attribute__((unused)) bool waiting_buffer_has_anykey_pressed(void) { | ||
| 369 | for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { | ||
| 370 | if (waiting_buffer[i].event.pressed) return true; | ||
| 371 | } | ||
| 372 | return false; | ||
| 373 | } | ||
| 374 | |||
| 375 | /** \brief Scan buffer for tapping | ||
| 376 | * | ||
| 377 | * FIXME: Needs docs | ||
| 378 | */ | ||
| 379 | void waiting_buffer_scan_tap(void) { | ||
| 380 | // tapping already is settled | ||
| 381 | if (tapping_key.tap.count > 0) return; | ||
| 382 | // invalid state: tapping_key released && tap.count == 0 | ||
| 383 | if (!tapping_key.event.pressed) return; | ||
| 384 | |||
| 385 | for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { | ||
| 386 | if (IS_TAPPING_KEY(waiting_buffer[i].event.key) && !waiting_buffer[i].event.pressed && WITHIN_TAPPING_TERM(waiting_buffer[i].event)) { | ||
| 387 | tapping_key.tap.count = 1; | ||
| 388 | waiting_buffer[i].tap.count = 1; | ||
| 389 | process_record(&tapping_key); | ||
| 390 | |||
| 391 | debug("waiting_buffer_scan_tap: found at ["); | ||
| 392 | debug_dec(i); | ||
| 393 | debug("]\n"); | ||
| 394 | debug_waiting_buffer(); | ||
| 395 | return; | ||
| 396 | } | ||
| 397 | } | ||
| 398 | } | ||
| 399 | |||
| 400 | /** \brief Tapping key debug print | ||
| 401 | * | ||
| 402 | * FIXME: Needs docs | ||
| 403 | */ | ||
| 404 | static void debug_tapping_key(void) { | ||
| 405 | debug("TAPPING_KEY="); | ||
| 406 | debug_record(tapping_key); | ||
| 407 | debug("\n"); | ||
| 408 | } | ||
| 409 | |||
| 410 | /** \brief Waiting buffer debug print | ||
| 411 | * | ||
| 412 | * FIXME: Needs docs | ||
| 413 | */ | ||
| 414 | static void debug_waiting_buffer(void) { | ||
| 415 | debug("{ "); | ||
| 416 | for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { | ||
| 417 | debug("["); | ||
| 418 | debug_dec(i); | ||
| 419 | debug("]="); | ||
| 420 | debug_record(waiting_buffer[i]); | ||
| 421 | debug(" "); | ||
| 422 | } | ||
| 423 | debug("}\n"); | ||
| 424 | } | ||
| 425 | |||
| 426 | #endif | ||
diff --git a/tmk_core/common/action_tapping.h b/tmk_core/common/action_tapping.h deleted file mode 100644 index 893ccb1ce..000000000 --- a/tmk_core/common/action_tapping.h +++ /dev/null | |||
| @@ -1,41 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | /* period of tapping(ms) */ | ||
| 21 | #ifndef TAPPING_TERM | ||
| 22 | # define TAPPING_TERM 200 | ||
| 23 | #endif | ||
| 24 | |||
| 25 | /* tap count needed for toggling a feature */ | ||
| 26 | #ifndef TAPPING_TOGGLE | ||
| 27 | # define TAPPING_TOGGLE 5 | ||
| 28 | #endif | ||
| 29 | |||
| 30 | #define WAITING_BUFFER_SIZE 8 | ||
| 31 | |||
| 32 | #ifndef NO_ACTION_TAPPING | ||
| 33 | uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache); | ||
| 34 | void action_tapping_process(keyrecord_t record); | ||
| 35 | |||
| 36 | uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record); | ||
| 37 | bool get_permissive_hold(uint16_t keycode, keyrecord_t *record); | ||
| 38 | bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record); | ||
| 39 | bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record); | ||
| 40 | bool get_retro_tapping(uint16_t keycode, keyrecord_t *record); | ||
| 41 | #endif | ||
diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c deleted file mode 100644 index a57c8bf66..000000000 --- a/tmk_core/common/action_util.c +++ /dev/null | |||
| @@ -1,427 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | #include "host.h" | ||
| 18 | #include "report.h" | ||
| 19 | #include "debug.h" | ||
| 20 | #include "action_util.h" | ||
| 21 | #include "action_layer.h" | ||
| 22 | #include "timer.h" | ||
| 23 | #include "keycode_config.h" | ||
| 24 | |||
| 25 | extern keymap_config_t keymap_config; | ||
| 26 | |||
| 27 | static uint8_t real_mods = 0; | ||
| 28 | static uint8_t weak_mods = 0; | ||
| 29 | static uint8_t macro_mods = 0; | ||
| 30 | |||
| 31 | #ifdef USB_6KRO_ENABLE | ||
| 32 | # define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS) | ||
| 33 | # define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS) | ||
| 34 | # define RO_INC(a) RO_ADD(a, 1) | ||
| 35 | # define RO_DEC(a) RO_SUB(a, 1) | ||
| 36 | static int8_t cb_head = 0; | ||
| 37 | static int8_t cb_tail = 0; | ||
| 38 | static int8_t cb_count = 0; | ||
| 39 | #endif | ||
| 40 | |||
| 41 | // TODO: pointer variable is not needed | ||
| 42 | // report_keyboard_t keyboard_report = {}; | ||
| 43 | report_keyboard_t *keyboard_report = &(report_keyboard_t){}; | ||
| 44 | |||
| 45 | extern inline void add_key(uint8_t key); | ||
| 46 | extern inline void del_key(uint8_t key); | ||
| 47 | extern inline void clear_keys(void); | ||
| 48 | |||
| 49 | #ifndef NO_ACTION_ONESHOT | ||
| 50 | static uint8_t oneshot_mods = 0; | ||
| 51 | static uint8_t oneshot_locked_mods = 0; | ||
| 52 | uint8_t get_oneshot_locked_mods(void) { return oneshot_locked_mods; } | ||
| 53 | void set_oneshot_locked_mods(uint8_t mods) { | ||
| 54 | if (mods != oneshot_locked_mods) { | ||
| 55 | oneshot_locked_mods = mods; | ||
| 56 | oneshot_locked_mods_changed_kb(oneshot_locked_mods); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | void clear_oneshot_locked_mods(void) { | ||
| 60 | if (oneshot_locked_mods) { | ||
| 61 | oneshot_locked_mods = 0; | ||
| 62 | oneshot_locked_mods_changed_kb(oneshot_locked_mods); | ||
| 63 | } | ||
| 64 | } | ||
| 65 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 66 | static uint16_t oneshot_time = 0; | ||
| 67 | bool has_oneshot_mods_timed_out(void) { return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; } | ||
| 68 | # else | ||
| 69 | bool has_oneshot_mods_timed_out(void) { return false; } | ||
| 70 | # endif | ||
| 71 | #endif | ||
| 72 | |||
| 73 | /* oneshot layer */ | ||
| 74 | #ifndef NO_ACTION_ONESHOT | ||
| 75 | /** \brief oneshot_layer_data bits | ||
| 76 | * LLLL LSSS | ||
| 77 | * where: | ||
| 78 | * L => are layer bits | ||
| 79 | * S => oneshot state bits | ||
| 80 | */ | ||
| 81 | static int8_t oneshot_layer_data = 0; | ||
| 82 | |||
| 83 | inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; } | ||
| 84 | inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; } | ||
| 85 | |||
| 86 | # ifdef SWAP_HANDS_ENABLE | ||
| 87 | enum { | ||
| 88 | SHO_OFF, | ||
| 89 | SHO_ACTIVE, // Swap hands button was pressed, and we didn't send any swapped keys yet | ||
| 90 | SHO_PRESSED, // Swap hands button is currently pressed | ||
| 91 | SHO_USED, // Swap hands button is still pressed, and we already sent swapped keys | ||
| 92 | } swap_hands_oneshot = SHO_OFF; | ||
| 93 | # endif | ||
| 94 | |||
| 95 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 96 | static uint16_t oneshot_layer_time = 0; | ||
| 97 | inline bool has_oneshot_layer_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && !(get_oneshot_layer_state() & ONESHOT_TOGGLED); } | ||
| 98 | # ifdef SWAP_HANDS_ENABLE | ||
| 99 | static uint16_t oneshot_swaphands_time = 0; | ||
| 100 | inline bool has_oneshot_swaphands_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_swaphands_time) >= ONESHOT_TIMEOUT && (swap_hands_oneshot == SHO_ACTIVE); } | ||
| 101 | # endif | ||
| 102 | # endif | ||
| 103 | |||
| 104 | # ifdef SWAP_HANDS_ENABLE | ||
| 105 | |||
| 106 | void set_oneshot_swaphands(void) { | ||
| 107 | swap_hands_oneshot = SHO_PRESSED; | ||
| 108 | swap_hands = true; | ||
| 109 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 110 | oneshot_swaphands_time = timer_read(); | ||
| 111 | if (oneshot_layer_time != 0) { | ||
| 112 | oneshot_layer_time = oneshot_swaphands_time; | ||
| 113 | } | ||
| 114 | # endif | ||
| 115 | } | ||
| 116 | |||
| 117 | void release_oneshot_swaphands(void) { | ||
| 118 | if (swap_hands_oneshot == SHO_PRESSED) { | ||
| 119 | swap_hands_oneshot = SHO_ACTIVE; | ||
| 120 | } | ||
| 121 | if (swap_hands_oneshot == SHO_USED) { | ||
| 122 | clear_oneshot_swaphands(); | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | void use_oneshot_swaphands(void) { | ||
| 127 | if (swap_hands_oneshot == SHO_PRESSED) { | ||
| 128 | swap_hands_oneshot = SHO_USED; | ||
| 129 | } | ||
| 130 | if (swap_hands_oneshot == SHO_ACTIVE) { | ||
| 131 | clear_oneshot_swaphands(); | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | void clear_oneshot_swaphands(void) { | ||
| 136 | swap_hands_oneshot = SHO_OFF; | ||
| 137 | swap_hands = false; | ||
| 138 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 139 | oneshot_swaphands_time = 0; | ||
| 140 | # endif | ||
| 141 | } | ||
| 142 | |||
| 143 | # endif | ||
| 144 | |||
| 145 | /** \brief Set oneshot layer | ||
| 146 | * | ||
| 147 | * FIXME: needs doc | ||
| 148 | */ | ||
| 149 | void set_oneshot_layer(uint8_t layer, uint8_t state) { | ||
| 150 | if (!keymap_config.oneshot_disable) { | ||
| 151 | oneshot_layer_data = layer << 3 | state; | ||
| 152 | layer_on(layer); | ||
| 153 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 154 | oneshot_layer_time = timer_read(); | ||
| 155 | # endif | ||
| 156 | oneshot_layer_changed_kb(get_oneshot_layer()); | ||
| 157 | } else { | ||
| 158 | layer_on(layer); | ||
| 159 | } | ||
| 160 | } | ||
| 161 | /** \brief Reset oneshot layer | ||
| 162 | * | ||
| 163 | * FIXME: needs doc | ||
| 164 | */ | ||
| 165 | void reset_oneshot_layer(void) { | ||
| 166 | oneshot_layer_data = 0; | ||
| 167 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 168 | oneshot_layer_time = 0; | ||
| 169 | # endif | ||
| 170 | oneshot_layer_changed_kb(get_oneshot_layer()); | ||
| 171 | } | ||
| 172 | /** \brief Clear oneshot layer | ||
| 173 | * | ||
| 174 | * FIXME: needs doc | ||
| 175 | */ | ||
| 176 | void clear_oneshot_layer_state(oneshot_fullfillment_t state) { | ||
| 177 | uint8_t start_state = oneshot_layer_data; | ||
| 178 | oneshot_layer_data &= ~state; | ||
| 179 | if ((!get_oneshot_layer_state() && start_state != oneshot_layer_data) || keymap_config.oneshot_disable) { | ||
| 180 | layer_off(get_oneshot_layer()); | ||
| 181 | reset_oneshot_layer(); | ||
| 182 | } | ||
| 183 | } | ||
| 184 | /** \brief Is oneshot layer active | ||
| 185 | * | ||
| 186 | * FIXME: needs doc | ||
| 187 | */ | ||
| 188 | bool is_oneshot_layer_active(void) { return get_oneshot_layer_state(); } | ||
| 189 | |||
| 190 | /** \brief set oneshot | ||
| 191 | * | ||
| 192 | * FIXME: needs doc | ||
| 193 | */ | ||
| 194 | void oneshot_set(bool active) { | ||
| 195 | if (keymap_config.oneshot_disable != active) { | ||
| 196 | keymap_config.oneshot_disable = active; | ||
| 197 | eeconfig_update_keymap(keymap_config.raw); | ||
| 198 | dprintf("Oneshot: active: %d\n", active); | ||
| 199 | } | ||
| 200 | } | ||
| 201 | |||
| 202 | /** \brief toggle oneshot | ||
| 203 | * | ||
| 204 | * FIXME: needs doc | ||
| 205 | */ | ||
| 206 | void oneshot_toggle(void) { oneshot_set(!keymap_config.oneshot_disable); } | ||
| 207 | |||
| 208 | /** \brief enable oneshot | ||
| 209 | * | ||
| 210 | * FIXME: needs doc | ||
| 211 | */ | ||
| 212 | void oneshot_enable(void) { oneshot_set(true); } | ||
| 213 | |||
| 214 | /** \brief disable oneshot | ||
| 215 | * | ||
| 216 | * FIXME: needs doc | ||
| 217 | */ | ||
| 218 | void oneshot_disable(void) { oneshot_set(false); } | ||
| 219 | |||
| 220 | bool is_oneshot_enabled(void) { return keymap_config.oneshot_disable; } | ||
| 221 | |||
| 222 | #endif | ||
| 223 | |||
| 224 | /** \brief Send keyboard report | ||
| 225 | * | ||
| 226 | * FIXME: needs doc | ||
| 227 | */ | ||
| 228 | void send_keyboard_report(void) { | ||
| 229 | keyboard_report->mods = real_mods; | ||
| 230 | keyboard_report->mods |= weak_mods; | ||
| 231 | keyboard_report->mods |= macro_mods; | ||
| 232 | #ifndef NO_ACTION_ONESHOT | ||
| 233 | if (oneshot_mods) { | ||
| 234 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 235 | if (has_oneshot_mods_timed_out()) { | ||
| 236 | dprintf("Oneshot: timeout\n"); | ||
| 237 | clear_oneshot_mods(); | ||
| 238 | } | ||
| 239 | # endif | ||
| 240 | keyboard_report->mods |= oneshot_mods; | ||
| 241 | if (has_anykey(keyboard_report)) { | ||
| 242 | clear_oneshot_mods(); | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 246 | #endif | ||
| 247 | host_keyboard_send(keyboard_report); | ||
| 248 | } | ||
| 249 | |||
| 250 | /** \brief Get mods | ||
| 251 | * | ||
| 252 | * FIXME: needs doc | ||
| 253 | */ | ||
| 254 | uint8_t get_mods(void) { return real_mods; } | ||
| 255 | /** \brief add mods | ||
| 256 | * | ||
| 257 | * FIXME: needs doc | ||
| 258 | */ | ||
| 259 | void add_mods(uint8_t mods) { real_mods |= mods; } | ||
| 260 | /** \brief del mods | ||
| 261 | * | ||
| 262 | * FIXME: needs doc | ||
| 263 | */ | ||
| 264 | void del_mods(uint8_t mods) { real_mods &= ~mods; } | ||
| 265 | /** \brief set mods | ||
| 266 | * | ||
| 267 | * FIXME: needs doc | ||
| 268 | */ | ||
| 269 | void set_mods(uint8_t mods) { real_mods = mods; } | ||
| 270 | /** \brief clear mods | ||
| 271 | * | ||
| 272 | * FIXME: needs doc | ||
| 273 | */ | ||
| 274 | void clear_mods(void) { real_mods = 0; } | ||
| 275 | |||
| 276 | /** \brief get weak mods | ||
| 277 | * | ||
| 278 | * FIXME: needs doc | ||
| 279 | */ | ||
| 280 | uint8_t get_weak_mods(void) { return weak_mods; } | ||
| 281 | /** \brief add weak mods | ||
| 282 | * | ||
| 283 | * FIXME: needs doc | ||
| 284 | */ | ||
| 285 | void add_weak_mods(uint8_t mods) { weak_mods |= mods; } | ||
| 286 | /** \brief del weak mods | ||
| 287 | * | ||
| 288 | * FIXME: needs doc | ||
| 289 | */ | ||
| 290 | void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; } | ||
| 291 | /** \brief set weak mods | ||
| 292 | * | ||
| 293 | * FIXME: needs doc | ||
| 294 | */ | ||
| 295 | void set_weak_mods(uint8_t mods) { weak_mods = mods; } | ||
| 296 | /** \brief clear weak mods | ||
| 297 | * | ||
| 298 | * FIXME: needs doc | ||
| 299 | */ | ||
| 300 | void clear_weak_mods(void) { weak_mods = 0; } | ||
| 301 | |||
| 302 | /* macro modifier */ | ||
| 303 | /** \brief get macro mods | ||
| 304 | * | ||
| 305 | * FIXME: needs doc | ||
| 306 | */ | ||
| 307 | uint8_t get_macro_mods(void) { return macro_mods; } | ||
| 308 | /** \brief add macro mods | ||
| 309 | * | ||
| 310 | * FIXME: needs doc | ||
| 311 | */ | ||
| 312 | void add_macro_mods(uint8_t mods) { macro_mods |= mods; } | ||
| 313 | /** \brief del macro mods | ||
| 314 | * | ||
| 315 | * FIXME: needs doc | ||
| 316 | */ | ||
| 317 | void del_macro_mods(uint8_t mods) { macro_mods &= ~mods; } | ||
| 318 | /** \brief set macro mods | ||
| 319 | * | ||
| 320 | * FIXME: needs doc | ||
| 321 | */ | ||
| 322 | void set_macro_mods(uint8_t mods) { macro_mods = mods; } | ||
| 323 | /** \brief clear macro mods | ||
| 324 | * | ||
| 325 | * FIXME: needs doc | ||
| 326 | */ | ||
| 327 | void clear_macro_mods(void) { macro_mods = 0; } | ||
| 328 | |||
| 329 | #ifndef NO_ACTION_ONESHOT | ||
| 330 | /** \brief get oneshot mods | ||
| 331 | * | ||
| 332 | * FIXME: needs doc | ||
| 333 | */ | ||
| 334 | uint8_t get_oneshot_mods(void) { return oneshot_mods; } | ||
| 335 | |||
| 336 | void add_oneshot_mods(uint8_t mods) { | ||
| 337 | if ((oneshot_mods & mods) != mods) { | ||
| 338 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 339 | oneshot_time = timer_read(); | ||
| 340 | # endif | ||
| 341 | oneshot_mods |= mods; | ||
| 342 | oneshot_mods_changed_kb(mods); | ||
| 343 | } | ||
| 344 | } | ||
| 345 | |||
| 346 | void del_oneshot_mods(uint8_t mods) { | ||
| 347 | if (oneshot_mods & mods) { | ||
| 348 | oneshot_mods &= ~mods; | ||
| 349 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 350 | oneshot_time = oneshot_mods ? timer_read() : 0; | ||
| 351 | # endif | ||
| 352 | oneshot_mods_changed_kb(oneshot_mods); | ||
| 353 | } | ||
| 354 | } | ||
| 355 | |||
| 356 | /** \brief set oneshot mods | ||
| 357 | * | ||
| 358 | * FIXME: needs doc | ||
| 359 | */ | ||
| 360 | void set_oneshot_mods(uint8_t mods) { | ||
| 361 | if (!keymap_config.oneshot_disable) { | ||
| 362 | if (oneshot_mods != mods) { | ||
| 363 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 364 | oneshot_time = timer_read(); | ||
| 365 | # endif | ||
| 366 | oneshot_mods = mods; | ||
| 367 | oneshot_mods_changed_kb(mods); | ||
| 368 | } | ||
| 369 | } | ||
| 370 | } | ||
| 371 | |||
| 372 | /** \brief clear oneshot mods | ||
| 373 | * | ||
| 374 | * FIXME: needs doc | ||
| 375 | */ | ||
| 376 | void clear_oneshot_mods(void) { | ||
| 377 | if (oneshot_mods) { | ||
| 378 | oneshot_mods = 0; | ||
| 379 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
| 380 | oneshot_time = 0; | ||
| 381 | # endif | ||
| 382 | oneshot_mods_changed_kb(oneshot_mods); | ||
| 383 | } | ||
| 384 | } | ||
| 385 | #endif | ||
| 386 | |||
| 387 | /** \brief Called when the one shot modifiers have been changed. | ||
| 388 | * | ||
| 389 | * \param mods Contains the active modifiers active after the change. | ||
| 390 | */ | ||
| 391 | __attribute__((weak)) void oneshot_locked_mods_changed_user(uint8_t mods) {} | ||
| 392 | |||
| 393 | /** \brief Called when the locked one shot modifiers have been changed. | ||
| 394 | * | ||
| 395 | * \param mods Contains the active modifiers active after the change. | ||
| 396 | */ | ||
| 397 | __attribute__((weak)) void oneshot_locked_mods_changed_kb(uint8_t mods) { oneshot_locked_mods_changed_user(mods); } | ||
| 398 | |||
| 399 | /** \brief Called when the one shot modifiers have been changed. | ||
| 400 | * | ||
| 401 | * \param mods Contains the active modifiers active after the change. | ||
| 402 | */ | ||
| 403 | __attribute__((weak)) void oneshot_mods_changed_user(uint8_t mods) {} | ||
| 404 | |||
| 405 | /** \brief Called when the one shot modifiers have been changed. | ||
| 406 | * | ||
| 407 | * \param mods Contains the active modifiers active after the change. | ||
| 408 | */ | ||
| 409 | __attribute__((weak)) void oneshot_mods_changed_kb(uint8_t mods) { oneshot_mods_changed_user(mods); } | ||
| 410 | |||
| 411 | /** \brief Called when the one shot layers have been changed. | ||
| 412 | * | ||
| 413 | * \param layer Contains the layer that is toggled on, or zero when toggled off. | ||
| 414 | */ | ||
| 415 | __attribute__((weak)) void oneshot_layer_changed_user(uint8_t layer) {} | ||
| 416 | |||
| 417 | /** \brief Called when the one shot layers have been changed. | ||
| 418 | * | ||
| 419 | * \param layer Contains the layer that is toggled on, or zero when toggled off. | ||
| 420 | */ | ||
| 421 | __attribute__((weak)) void oneshot_layer_changed_kb(uint8_t layer) { oneshot_layer_changed_user(layer); } | ||
| 422 | |||
| 423 | /** \brief inspect keyboard state | ||
| 424 | * | ||
| 425 | * FIXME: needs doc | ||
| 426 | */ | ||
| 427 | uint8_t has_anymod(void) { return bitpop(real_mods); } | ||
diff --git a/tmk_core/common/action_util.h b/tmk_core/common/action_util.h deleted file mode 100644 index f2b3897ae..000000000 --- a/tmk_core/common/action_util.h +++ /dev/null | |||
| @@ -1,105 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <stdint.h> | ||
| 21 | #include "report.h" | ||
| 22 | |||
| 23 | #ifdef __cplusplus | ||
| 24 | extern "C" { | ||
| 25 | #endif | ||
| 26 | |||
| 27 | extern report_keyboard_t *keyboard_report; | ||
| 28 | |||
| 29 | void send_keyboard_report(void); | ||
| 30 | |||
| 31 | /* key */ | ||
| 32 | inline void add_key(uint8_t key) { add_key_to_report(keyboard_report, key); } | ||
| 33 | |||
| 34 | inline void del_key(uint8_t key) { del_key_from_report(keyboard_report, key); } | ||
| 35 | |||
| 36 | inline void clear_keys(void) { clear_keys_from_report(keyboard_report); } | ||
| 37 | |||
| 38 | /* modifier */ | ||
| 39 | uint8_t get_mods(void); | ||
| 40 | void add_mods(uint8_t mods); | ||
| 41 | void del_mods(uint8_t mods); | ||
| 42 | void set_mods(uint8_t mods); | ||
| 43 | void clear_mods(void); | ||
| 44 | |||
| 45 | /* weak modifier */ | ||
| 46 | uint8_t get_weak_mods(void); | ||
| 47 | void add_weak_mods(uint8_t mods); | ||
| 48 | void del_weak_mods(uint8_t mods); | ||
| 49 | void set_weak_mods(uint8_t mods); | ||
| 50 | void clear_weak_mods(void); | ||
| 51 | |||
| 52 | /* macro modifier */ | ||
| 53 | uint8_t get_macro_mods(void); | ||
| 54 | void add_macro_mods(uint8_t mods); | ||
| 55 | void del_macro_mods(uint8_t mods); | ||
| 56 | void set_macro_mods(uint8_t mods); | ||
| 57 | void clear_macro_mods(void); | ||
| 58 | |||
| 59 | /* oneshot modifier */ | ||
| 60 | uint8_t get_oneshot_mods(void); | ||
| 61 | void add_oneshot_mods(uint8_t mods); | ||
| 62 | void del_oneshot_mods(uint8_t mods); | ||
| 63 | void set_oneshot_mods(uint8_t mods); | ||
| 64 | void clear_oneshot_mods(void); | ||
| 65 | bool has_oneshot_mods_timed_out(void); | ||
| 66 | |||
| 67 | uint8_t get_oneshot_locked_mods(void); | ||
| 68 | void set_oneshot_locked_mods(uint8_t mods); | ||
| 69 | void clear_oneshot_locked_mods(void); | ||
| 70 | |||
| 71 | typedef enum { ONESHOT_PRESSED = 0b01, ONESHOT_OTHER_KEY_PRESSED = 0b10, ONESHOT_START = 0b11, ONESHOT_TOGGLED = 0b100 } oneshot_fullfillment_t; | ||
| 72 | void set_oneshot_layer(uint8_t layer, uint8_t state); | ||
| 73 | uint8_t get_oneshot_layer(void); | ||
| 74 | void clear_oneshot_layer_state(oneshot_fullfillment_t state); | ||
| 75 | void reset_oneshot_layer(void); | ||
| 76 | bool is_oneshot_layer_active(void); | ||
| 77 | uint8_t get_oneshot_layer_state(void); | ||
| 78 | bool has_oneshot_layer_timed_out(void); | ||
| 79 | bool has_oneshot_swaphands_timed_out(void); | ||
| 80 | |||
| 81 | void oneshot_locked_mods_changed_user(uint8_t mods); | ||
| 82 | void oneshot_locked_mods_changed_kb(uint8_t mods); | ||
| 83 | void oneshot_mods_changed_user(uint8_t mods); | ||
| 84 | void oneshot_mods_changed_kb(uint8_t mods); | ||
| 85 | void oneshot_layer_changed_user(uint8_t layer); | ||
| 86 | void oneshot_layer_changed_kb(uint8_t layer); | ||
| 87 | |||
| 88 | void oneshot_toggle(void); | ||
| 89 | void oneshot_enable(void); | ||
| 90 | void oneshot_disable(void); | ||
| 91 | bool is_oneshot_enabled(void); | ||
| 92 | |||
| 93 | /* inspect */ | ||
| 94 | uint8_t has_anymod(void); | ||
| 95 | |||
| 96 | #ifdef SWAP_HANDS_ENABLE | ||
| 97 | void set_oneshot_swaphands(void); | ||
| 98 | void release_oneshot_swaphands(void); | ||
| 99 | void use_oneshot_swaphands(void); | ||
| 100 | void clear_oneshot_swaphands(void); | ||
| 101 | #endif | ||
| 102 | |||
| 103 | #ifdef __cplusplus | ||
| 104 | } | ||
| 105 | #endif | ||
diff --git a/tmk_core/common/arm_atsam/_timer.h b/tmk_core/common/arm_atsam/_timer.h new file mode 100644 index 000000000..77402b612 --- /dev/null +++ b/tmk_core/common/arm_atsam/_timer.h | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* Copyright 2021 Simon Arlott | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #pragma once | ||
| 17 | |||
| 18 | // The platform is 32-bit, so prefer 32-bit timers to avoid overflow | ||
| 19 | #define FAST_TIMER_T_SIZE 32 | ||
diff --git a/tmk_core/common/arm_atsam/platform.c b/tmk_core/common/arm_atsam/platform.c new file mode 100644 index 000000000..3e35b4fe4 --- /dev/null +++ b/tmk_core/common/arm_atsam/platform.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* Copyright 2021 QMK | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 3 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "platform_deps.h" | ||
| 18 | |||
| 19 | void platform_setup(void) { | ||
| 20 | // do nothing | ||
| 21 | } | ||
diff --git a/tmk_core/common/avr/_timer.h b/tmk_core/common/avr/_timer.h new file mode 100644 index 000000000..b81e0f68b --- /dev/null +++ b/tmk_core/common/avr/_timer.h | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* Copyright 2021 Simon Arlott | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #pragma once | ||
| 17 | |||
| 18 | // The platform is 8-bit, so prefer 16-bit timers to reduce code size | ||
| 19 | #define FAST_TIMER_T_SIZE 16 | ||
diff --git a/tmk_core/common/avr/_wait.h b/tmk_core/common/avr/_wait.h index 56eb316fa..ae1a25131 100644 --- a/tmk_core/common/avr/_wait.h +++ b/tmk_core/common/avr/_wait.h | |||
| @@ -17,8 +17,26 @@ | |||
| 17 | 17 | ||
| 18 | #include <util/delay.h> | 18 | #include <util/delay.h> |
| 19 | 19 | ||
| 20 | #define wait_ms(ms) _delay_ms(ms) | 20 | #define wait_ms(ms) \ |
| 21 | #define wait_us(us) _delay_us(us) | 21 | do { \ |
| 22 | if (__builtin_constant_p(ms)) { \ | ||
| 23 | _delay_ms(ms); \ | ||
| 24 | } else { \ | ||
| 25 | for (uint16_t i = ms; i > 0; i--) { \ | ||
| 26 | _delay_ms(1); \ | ||
| 27 | } \ | ||
| 28 | } \ | ||
| 29 | } while (0) | ||
| 30 | #define wait_us(us) \ | ||
| 31 | do { \ | ||
| 32 | if (__builtin_constant_p(us)) { \ | ||
| 33 | _delay_us(us); \ | ||
| 34 | } else { \ | ||
| 35 | for (uint16_t i = us; i > 0; i--) { \ | ||
| 36 | _delay_us(1); \ | ||
| 37 | } \ | ||
| 38 | } \ | ||
| 39 | } while (0) | ||
| 22 | 40 | ||
| 23 | /* The AVR series GPIOs have a one clock read delay for changes in the digital input signal. | 41 | /* The AVR series GPIOs have a one clock read delay for changes in the digital input signal. |
| 24 | * But here's more margin to make it two clocks. */ | 42 | * But here's more margin to make it two clocks. */ |
diff --git a/tmk_core/common/avr/gpio.h b/tmk_core/common/avr/gpio.h index 231556c29..e9be68491 100644 --- a/tmk_core/common/avr/gpio.h +++ b/tmk_core/common/avr/gpio.h | |||
| @@ -20,6 +20,8 @@ | |||
| 20 | 20 | ||
| 21 | typedef uint8_t pin_t; | 21 | typedef uint8_t pin_t; |
| 22 | 22 | ||
| 23 | /* Operation of GPIO by pin. */ | ||
| 24 | |||
| 23 | #define setPinInput(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) | 25 | #define setPinInput(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) |
| 24 | #define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) | 26 | #define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) |
| 25 | #define setPinInputLow(pin) _Static_assert(0, "AVR processors cannot implement an input as pull low") | 27 | #define setPinInputLow(pin) _Static_assert(0, "AVR processors cannot implement an input as pull low") |
| @@ -32,3 +34,16 @@ typedef uint8_t pin_t; | |||
| 32 | #define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF))) | 34 | #define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF))) |
| 33 | 35 | ||
| 34 | #define togglePin(pin) (PORTx_ADDRESS(pin) ^= _BV((pin)&0xF)) | 36 | #define togglePin(pin) (PORTx_ADDRESS(pin) ^= _BV((pin)&0xF)) |
| 37 | |||
| 38 | /* Operation of GPIO by port. */ | ||
| 39 | |||
| 40 | typedef uint8_t port_data_t; | ||
| 41 | |||
| 42 | #define readPort(port) PINx_ADDRESS(port) | ||
| 43 | |||
| 44 | #define setPortBitInput(port, bit) (DDRx_ADDRESS(port) &= ~_BV((bit)&0xF), PORTx_ADDRESS(port) &= ~_BV((bit)&0xF)) | ||
| 45 | #define setPortBitInputHigh(port, bit) (DDRx_ADDRESS(port) &= ~_BV((bit)&0xF), PORTx_ADDRESS(port) |= _BV((bit)&0xF)) | ||
| 46 | #define setPortBitOutput(port, bit) (DDRx_ADDRESS(port) |= _BV((bit)&0xF)) | ||
| 47 | |||
| 48 | #define writePortBitLow(port, bit) (PORTx_ADDRESS(port) &= ~_BV((bit)&0xF)) | ||
| 49 | #define writePortBitHigh(port, bit) (PORTx_ADDRESS(port) |= _BV((bit)&0xF)) | ||
diff --git a/tmk_core/common/avr/platform.c b/tmk_core/common/avr/platform.c new file mode 100644 index 000000000..3e35b4fe4 --- /dev/null +++ b/tmk_core/common/avr/platform.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* Copyright 2021 QMK | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 3 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "platform_deps.h" | ||
| 18 | |||
| 19 | void platform_setup(void) { | ||
| 20 | // do nothing | ||
| 21 | } | ||
diff --git a/tmk_core/common/chibios/_timer.h b/tmk_core/common/chibios/_timer.h new file mode 100644 index 000000000..77402b612 --- /dev/null +++ b/tmk_core/common/chibios/_timer.h | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* Copyright 2021 Simon Arlott | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #pragma once | ||
| 17 | |||
| 18 | // The platform is 32-bit, so prefer 32-bit timers to avoid overflow | ||
| 19 | #define FAST_TIMER_T_SIZE 32 | ||
diff --git a/tmk_core/common/chibios/bootloader.c b/tmk_core/common/chibios/bootloader.c index 11f7abf43..f9514ee5f 100644 --- a/tmk_core/common/chibios/bootloader.c +++ b/tmk_core/common/chibios/bootloader.c | |||
| @@ -95,7 +95,7 @@ void enter_bootloader_mode_if_requested(void) { | |||
| 95 | } | 95 | } |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | #elif defined(KL2x) || defined(K20x) || defined(MK66F18) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS | 98 | #elif defined(KL2x) || defined(K20x) || defined(MK66F18) || defined(MIMXRT1062) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS |
| 99 | /* Kinetis */ | 99 | /* Kinetis */ |
| 100 | 100 | ||
| 101 | # if defined(BOOTLOADER_KIIBOHD) | 101 | # if defined(BOOTLOADER_KIIBOHD) |
| @@ -103,7 +103,8 @@ void enter_bootloader_mode_if_requested(void) { | |||
| 103 | # define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000 | 103 | # define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000 |
| 104 | const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff"; | 104 | const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff"; |
| 105 | __attribute__((weak)) void bootloader_jump(void) { | 105 | __attribute__((weak)) void bootloader_jump(void) { |
| 106 | __builtin_memcpy((void *)VBAT, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic)); | 106 | void *volatile vbat = (void *)VBAT; |
| 107 | __builtin_memcpy(vbat, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic)); | ||
| 107 | // request reset | 108 | // request reset |
| 108 | SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk; | 109 | SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk; |
| 109 | } | 110 | } |
diff --git a/tmk_core/common/chibios/gpio.h b/tmk_core/common/chibios/gpio.h index 5d0e142ab..4d057f1ca 100644 --- a/tmk_core/common/chibios/gpio.h +++ b/tmk_core/common/chibios/gpio.h | |||
| @@ -20,6 +20,8 @@ | |||
| 20 | 20 | ||
| 21 | typedef ioline_t pin_t; | 21 | typedef ioline_t pin_t; |
| 22 | 22 | ||
| 23 | /* Operation of GPIO by pin. */ | ||
| 24 | |||
| 23 | #define setPinInput(pin) palSetLineMode(pin, PAL_MODE_INPUT) | 25 | #define setPinInput(pin) palSetLineMode(pin, PAL_MODE_INPUT) |
| 24 | #define setPinInputHigh(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLUP) | 26 | #define setPinInputHigh(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLUP) |
| 25 | #define setPinInputLow(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN) | 27 | #define setPinInputLow(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN) |
| @@ -32,3 +34,17 @@ typedef ioline_t pin_t; | |||
| 32 | #define readPin(pin) palReadLine(pin) | 34 | #define readPin(pin) palReadLine(pin) |
| 33 | 35 | ||
| 34 | #define togglePin(pin) palToggleLine(pin) | 36 | #define togglePin(pin) palToggleLine(pin) |
| 37 | |||
| 38 | /* Operation of GPIO by port. */ | ||
| 39 | |||
| 40 | typedef uint16_t port_data_t; | ||
| 41 | |||
| 42 | #define readPort(pin) palReadPort(PAL_PORT(pin)) | ||
| 43 | |||
| 44 | #define setPortBitInput(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT) | ||
| 45 | #define setPortBitInputHigh(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT_PULLUP) | ||
| 46 | #define setPortBitInputLow(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT_PULLDOWN) | ||
| 47 | #define setPortBitOutput(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_OUTPUT_PUSHPULL) | ||
| 48 | |||
| 49 | #define writePortBitLow(pin, bit) palClearLine(PAL_LINE(PAL_PORT(pin), bit)) | ||
| 50 | #define writePortBitHigh(pin, bit) palSetLine(PAL_LINE(PAL_PORT(pin), bit)) | ||
diff --git a/tmk_core/common/chibios/platform.c b/tmk_core/common/chibios/platform.c new file mode 100644 index 000000000..d4a229f27 --- /dev/null +++ b/tmk_core/common/chibios/platform.c | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | /* Copyright 2021 QMK | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 3 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "platform_deps.h" | ||
| 18 | |||
| 19 | void platform_setup(void) { | ||
| 20 | halInit(); | ||
| 21 | chSysInit(); | ||
| 22 | } \ No newline at end of file | ||
diff --git a/tmk_core/common/debug.c b/tmk_core/common/debug.c deleted file mode 100644 index ea62deaa8..000000000 --- a/tmk_core/common/debug.c +++ /dev/null | |||
| @@ -1,25 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | #include "debug.h" | ||
| 18 | |||
| 19 | debug_config_t debug_config = { | ||
| 20 | .enable = false, // | ||
| 21 | .matrix = false, // | ||
| 22 | .keyboard = false, // | ||
| 23 | .mouse = false, // | ||
| 24 | .reserved = 0 // | ||
| 25 | }; | ||
diff --git a/tmk_core/common/debug.h b/tmk_core/common/debug.h deleted file mode 100644 index 3d2e2315e..000000000 --- a/tmk_core/common/debug.h +++ /dev/null | |||
| @@ -1,169 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <stdbool.h> | ||
| 21 | #include "print.h" | ||
| 22 | |||
| 23 | #ifdef __cplusplus | ||
| 24 | extern "C" { | ||
| 25 | #endif | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Debug output control | ||
| 29 | */ | ||
| 30 | typedef union { | ||
| 31 | struct { | ||
| 32 | bool enable : 1; | ||
| 33 | bool matrix : 1; | ||
| 34 | bool keyboard : 1; | ||
| 35 | bool mouse : 1; | ||
| 36 | uint8_t reserved : 4; | ||
| 37 | }; | ||
| 38 | uint8_t raw; | ||
| 39 | } debug_config_t; | ||
| 40 | |||
| 41 | extern debug_config_t debug_config; | ||
| 42 | |||
| 43 | #ifdef __cplusplus | ||
| 44 | } | ||
| 45 | #endif | ||
| 46 | |||
| 47 | /* for backward compatibility */ | ||
| 48 | #define debug_enable (debug_config.enable) | ||
| 49 | #define debug_matrix (debug_config.matrix) | ||
| 50 | #define debug_keyboard (debug_config.keyboard) | ||
| 51 | #define debug_mouse (debug_config.mouse) | ||
| 52 | |||
| 53 | /* | ||
| 54 | * Debug print utils | ||
| 55 | */ | ||
| 56 | #ifndef NO_DEBUG | ||
| 57 | |||
| 58 | # define dprint(s) \ | ||
| 59 | do { \ | ||
| 60 | if (debug_enable) print(s); \ | ||
| 61 | } while (0) | ||
| 62 | # define dprintln(s) \ | ||
| 63 | do { \ | ||
| 64 | if (debug_enable) println(s); \ | ||
| 65 | } while (0) | ||
| 66 | # define dprintf(fmt, ...) \ | ||
| 67 | do { \ | ||
| 68 | if (debug_enable) xprintf(fmt, ##__VA_ARGS__); \ | ||
| 69 | } while (0) | ||
| 70 | # define dmsg(s) dprintf("%s at %s: %S\n", __FILE__, __LINE__, PSTR(s)) | ||
| 71 | |||
| 72 | /* Deprecated. DO NOT USE these anymore, use dprintf instead. */ | ||
| 73 | # define debug(s) \ | ||
| 74 | do { \ | ||
| 75 | if (debug_enable) print(s); \ | ||
| 76 | } while (0) | ||
| 77 | # define debugln(s) \ | ||
| 78 | do { \ | ||
| 79 | if (debug_enable) println(s); \ | ||
| 80 | } while (0) | ||
| 81 | # define debug_msg(s) \ | ||
| 82 | do { \ | ||
| 83 | if (debug_enable) { \ | ||
| 84 | print(__FILE__); \ | ||
| 85 | print(" at "); \ | ||
| 86 | print_dec(__LINE__); \ | ||
| 87 | print(" in "); \ | ||
| 88 | print(": "); \ | ||
| 89 | print(s); \ | ||
| 90 | } \ | ||
| 91 | } while (0) | ||
| 92 | # define debug_dec(data) \ | ||
| 93 | do { \ | ||
| 94 | if (debug_enable) print_dec(data); \ | ||
| 95 | } while (0) | ||
| 96 | # define debug_decs(data) \ | ||
| 97 | do { \ | ||
| 98 | if (debug_enable) print_decs(data); \ | ||
| 99 | } while (0) | ||
| 100 | # define debug_hex4(data) \ | ||
| 101 | do { \ | ||
| 102 | if (debug_enable) print_hex4(data); \ | ||
| 103 | } while (0) | ||
| 104 | # define debug_hex8(data) \ | ||
| 105 | do { \ | ||
| 106 | if (debug_enable) print_hex8(data); \ | ||
| 107 | } while (0) | ||
| 108 | # define debug_hex16(data) \ | ||
| 109 | do { \ | ||
| 110 | if (debug_enable) print_hex16(data); \ | ||
| 111 | } while (0) | ||
| 112 | # define debug_hex32(data) \ | ||
| 113 | do { \ | ||
| 114 | if (debug_enable) print_hex32(data); \ | ||
| 115 | } while (0) | ||
| 116 | # define debug_bin8(data) \ | ||
| 117 | do { \ | ||
| 118 | if (debug_enable) print_bin8(data); \ | ||
| 119 | } while (0) | ||
| 120 | # define debug_bin16(data) \ | ||
| 121 | do { \ | ||
| 122 | if (debug_enable) print_bin16(data); \ | ||
| 123 | } while (0) | ||
| 124 | # define debug_bin32(data) \ | ||
| 125 | do { \ | ||
| 126 | if (debug_enable) print_bin32(data); \ | ||
| 127 | } while (0) | ||
| 128 | # define debug_bin_reverse8(data) \ | ||
| 129 | do { \ | ||
| 130 | if (debug_enable) print_bin_reverse8(data); \ | ||
| 131 | } while (0) | ||
| 132 | # define debug_bin_reverse16(data) \ | ||
| 133 | do { \ | ||
| 134 | if (debug_enable) print_bin_reverse16(data); \ | ||
| 135 | } while (0) | ||
| 136 | # define debug_bin_reverse32(data) \ | ||
| 137 | do { \ | ||
| 138 | if (debug_enable) print_bin_reverse32(data); \ | ||
| 139 | } while (0) | ||
| 140 | # define debug_hex(data) debug_hex8(data) | ||
| 141 | # define debug_bin(data) debug_bin8(data) | ||
| 142 | # define debug_bin_reverse(data) debug_bin8(data) | ||
| 143 | |||
| 144 | #else /* NO_DEBUG */ | ||
| 145 | |||
| 146 | # define dprint(s) | ||
| 147 | # define dprintln(s) | ||
| 148 | # define dprintf(fmt, ...) | ||
| 149 | # define dmsg(s) | ||
| 150 | # define debug(s) | ||
| 151 | # define debugln(s) | ||
| 152 | # define debug_msg(s) | ||
| 153 | # define debug_dec(data) | ||
| 154 | # define debug_decs(data) | ||
| 155 | # define debug_hex4(data) | ||
| 156 | # define debug_hex8(data) | ||
| 157 | # define debug_hex16(data) | ||
| 158 | # define debug_hex32(data) | ||
| 159 | # define debug_bin8(data) | ||
| 160 | # define debug_bin16(data) | ||
| 161 | # define debug_bin32(data) | ||
| 162 | # define debug_bin_reverse8(data) | ||
| 163 | # define debug_bin_reverse16(data) | ||
| 164 | # define debug_bin_reverse32(data) | ||
| 165 | # define debug_hex(data) | ||
| 166 | # define debug_bin(data) | ||
| 167 | # define debug_bin_reverse(data) | ||
| 168 | |||
| 169 | #endif /* NO_DEBUG */ | ||
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c deleted file mode 100644 index ffa56ab56..000000000 --- a/tmk_core/common/eeconfig.c +++ /dev/null | |||
| @@ -1,211 +0,0 @@ | |||
| 1 | #include <stdint.h> | ||
| 2 | #include <stdbool.h> | ||
| 3 | #include "eeprom.h" | ||
| 4 | #include "eeconfig.h" | ||
| 5 | #include "action_layer.h" | ||
| 6 | |||
| 7 | #ifdef STM32_EEPROM_ENABLE | ||
| 8 | # include <hal.h> | ||
| 9 | # include "eeprom_stm32.h" | ||
| 10 | #endif | ||
| 11 | |||
| 12 | #if defined(EEPROM_DRIVER) | ||
| 13 | # include "eeprom_driver.h" | ||
| 14 | #endif | ||
| 15 | |||
| 16 | #if defined(HAPTIC_ENABLE) | ||
| 17 | # include "haptic.h" | ||
| 18 | #endif | ||
| 19 | |||
| 20 | /** \brief eeconfig enable | ||
| 21 | * | ||
| 22 | * FIXME: needs doc | ||
| 23 | */ | ||
| 24 | __attribute__((weak)) void eeconfig_init_user(void) { | ||
| 25 | // Reset user EEPROM value to blank, rather than to a set value | ||
| 26 | eeconfig_update_user(0); | ||
| 27 | } | ||
| 28 | |||
| 29 | __attribute__((weak)) void eeconfig_init_kb(void) { | ||
| 30 | // Reset Keyboard EEPROM value to blank, rather than to a set value | ||
| 31 | eeconfig_update_kb(0); | ||
| 32 | |||
| 33 | eeconfig_init_user(); | ||
| 34 | } | ||
| 35 | |||
| 36 | /* | ||
| 37 | * FIXME: needs doc | ||
| 38 | */ | ||
| 39 | void eeconfig_init_quantum(void) { | ||
| 40 | #ifdef STM32_EEPROM_ENABLE | ||
| 41 | EEPROM_Erase(); | ||
| 42 | #endif | ||
| 43 | #if defined(EEPROM_DRIVER) | ||
| 44 | eeprom_driver_erase(); | ||
| 45 | #endif | ||
| 46 | eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); | ||
| 47 | eeprom_update_byte(EECONFIG_DEBUG, 0); | ||
| 48 | eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0); | ||
| 49 | default_layer_state = 0; | ||
| 50 | eeprom_update_byte(EECONFIG_KEYMAP_LOWER_BYTE, 0); | ||
| 51 | eeprom_update_byte(EECONFIG_KEYMAP_UPPER_BYTE, 0); | ||
| 52 | eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0); | ||
| 53 | eeprom_update_byte(EECONFIG_BACKLIGHT, 0); | ||
| 54 | eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default | ||
| 55 | eeprom_update_dword(EECONFIG_RGBLIGHT, 0); | ||
| 56 | eeprom_update_byte(EECONFIG_STENOMODE, 0); | ||
| 57 | eeprom_update_dword(EECONFIG_HAPTIC, 0); | ||
| 58 | eeprom_update_byte(EECONFIG_VELOCIKEY, 0); | ||
| 59 | eeprom_update_dword(EECONFIG_RGB_MATRIX, 0); | ||
| 60 | eeprom_update_word(EECONFIG_RGB_MATRIX_EXTENDED, 0); | ||
| 61 | |||
| 62 | // TODO: Remove once ARM has a way to configure EECONFIG_HANDEDNESS | ||
| 63 | // within the emulated eeprom via dfu-util or another tool | ||
| 64 | #if defined INIT_EE_HANDS_LEFT | ||
| 65 | # pragma message "Faking EE_HANDS for left hand" | ||
| 66 | eeprom_update_byte(EECONFIG_HANDEDNESS, 1); | ||
| 67 | #elif defined INIT_EE_HANDS_RIGHT | ||
| 68 | # pragma message "Faking EE_HANDS for right hand" | ||
| 69 | eeprom_update_byte(EECONFIG_HANDEDNESS, 0); | ||
| 70 | #endif | ||
| 71 | |||
| 72 | #if defined(HAPTIC_ENABLE) | ||
| 73 | haptic_reset(); | ||
| 74 | #else | ||
| 75 | // this is used in case haptic is disabled, but we still want sane defaults | ||
| 76 | // in the haptic configuration eeprom. All zero will trigger a haptic_reset | ||
| 77 | // when a haptic-enabled firmware is loaded onto the keyboard. | ||
| 78 | eeprom_update_dword(EECONFIG_HAPTIC, 0); | ||
| 79 | #endif | ||
| 80 | |||
| 81 | eeconfig_init_kb(); | ||
| 82 | } | ||
| 83 | |||
| 84 | /** \brief eeconfig initialization | ||
| 85 | * | ||
| 86 | * FIXME: needs doc | ||
| 87 | */ | ||
| 88 | void eeconfig_init(void) { eeconfig_init_quantum(); } | ||
| 89 | |||
| 90 | /** \brief eeconfig enable | ||
| 91 | * | ||
| 92 | * FIXME: needs doc | ||
| 93 | */ | ||
| 94 | void eeconfig_enable(void) { eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); } | ||
| 95 | |||
| 96 | /** \brief eeconfig disable | ||
| 97 | * | ||
| 98 | * FIXME: needs doc | ||
| 99 | */ | ||
| 100 | void eeconfig_disable(void) { | ||
| 101 | #ifdef STM32_EEPROM_ENABLE | ||
| 102 | EEPROM_Erase(); | ||
| 103 | #endif | ||
| 104 | #if defined(EEPROM_DRIVER) | ||
| 105 | eeprom_driver_erase(); | ||
| 106 | #endif | ||
| 107 | eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF); | ||
| 108 | } | ||
| 109 | |||
| 110 | /** \brief eeconfig is enabled | ||
| 111 | * | ||
| 112 | * FIXME: needs doc | ||
| 113 | */ | ||
| 114 | bool eeconfig_is_enabled(void) { return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER); } | ||
| 115 | |||
| 116 | /** \brief eeconfig is disabled | ||
| 117 | * | ||
| 118 | * FIXME: needs doc | ||
| 119 | */ | ||
| 120 | bool eeconfig_is_disabled(void) { return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF); } | ||
| 121 | |||
| 122 | /** \brief eeconfig read debug | ||
| 123 | * | ||
| 124 | * FIXME: needs doc | ||
| 125 | */ | ||
| 126 | uint8_t eeconfig_read_debug(void) { return eeprom_read_byte(EECONFIG_DEBUG); } | ||
| 127 | /** \brief eeconfig update debug | ||
| 128 | * | ||
| 129 | * FIXME: needs doc | ||
| 130 | */ | ||
| 131 | void eeconfig_update_debug(uint8_t val) { eeprom_update_byte(EECONFIG_DEBUG, val); } | ||
| 132 | |||
| 133 | /** \brief eeconfig read default layer | ||
| 134 | * | ||
| 135 | * FIXME: needs doc | ||
| 136 | */ | ||
| 137 | uint8_t eeconfig_read_default_layer(void) { return eeprom_read_byte(EECONFIG_DEFAULT_LAYER); } | ||
| 138 | /** \brief eeconfig update default layer | ||
| 139 | * | ||
| 140 | * FIXME: needs doc | ||
| 141 | */ | ||
| 142 | void eeconfig_update_default_layer(uint8_t val) { eeprom_update_byte(EECONFIG_DEFAULT_LAYER, val); } | ||
| 143 | |||
| 144 | /** \brief eeconfig read keymap | ||
| 145 | * | ||
| 146 | * FIXME: needs doc | ||
| 147 | */ | ||
| 148 | uint16_t eeconfig_read_keymap(void) { return (eeprom_read_byte(EECONFIG_KEYMAP_LOWER_BYTE) | (eeprom_read_byte(EECONFIG_KEYMAP_UPPER_BYTE) << 8)); } | ||
| 149 | /** \brief eeconfig update keymap | ||
| 150 | * | ||
| 151 | * FIXME: needs doc | ||
| 152 | */ | ||
| 153 | void eeconfig_update_keymap(uint16_t val) { | ||
| 154 | eeprom_update_byte(EECONFIG_KEYMAP_LOWER_BYTE, val & 0xFF); | ||
| 155 | eeprom_update_byte(EECONFIG_KEYMAP_UPPER_BYTE, (val >> 8) & 0xFF); | ||
| 156 | } | ||
| 157 | |||
| 158 | /** \brief eeconfig read audio | ||
| 159 | * | ||
| 160 | * FIXME: needs doc | ||
| 161 | */ | ||
| 162 | uint8_t eeconfig_read_audio(void) { return eeprom_read_byte(EECONFIG_AUDIO); } | ||
| 163 | /** \brief eeconfig update audio | ||
| 164 | * | ||
| 165 | * FIXME: needs doc | ||
| 166 | */ | ||
| 167 | void eeconfig_update_audio(uint8_t val) { eeprom_update_byte(EECONFIG_AUDIO, val); } | ||
| 168 | |||
| 169 | /** \brief eeconfig read kb | ||
| 170 | * | ||
| 171 | * FIXME: needs doc | ||
| 172 | */ | ||
| 173 | uint32_t eeconfig_read_kb(void) { return eeprom_read_dword(EECONFIG_KEYBOARD); } | ||
| 174 | /** \brief eeconfig update kb | ||
| 175 | * | ||
| 176 | * FIXME: needs doc | ||
| 177 | */ | ||
| 178 | void eeconfig_update_kb(uint32_t val) { eeprom_update_dword(EECONFIG_KEYBOARD, val); } | ||
| 179 | |||
| 180 | /** \brief eeconfig read user | ||
| 181 | * | ||
| 182 | * FIXME: needs doc | ||
| 183 | */ | ||
| 184 | uint32_t eeconfig_read_user(void) { return eeprom_read_dword(EECONFIG_USER); } | ||
| 185 | /** \brief eeconfig update user | ||
| 186 | * | ||
| 187 | * FIXME: needs doc | ||
| 188 | */ | ||
| 189 | void eeconfig_update_user(uint32_t val) { eeprom_update_dword(EECONFIG_USER, val); } | ||
| 190 | |||
| 191 | /** \brief eeconfig read haptic | ||
| 192 | * | ||
| 193 | * FIXME: needs doc | ||
| 194 | */ | ||
| 195 | uint32_t eeconfig_read_haptic(void) { return eeprom_read_dword(EECONFIG_HAPTIC); } | ||
| 196 | /** \brief eeconfig update haptic | ||
| 197 | * | ||
| 198 | * FIXME: needs doc | ||
| 199 | */ | ||
| 200 | void eeconfig_update_haptic(uint32_t val) { eeprom_update_dword(EECONFIG_HAPTIC, val); } | ||
| 201 | |||
| 202 | /** \brief eeconfig read split handedness | ||
| 203 | * | ||
| 204 | * FIXME: needs doc | ||
| 205 | */ | ||
| 206 | bool eeconfig_read_handedness(void) { return !!eeprom_read_byte(EECONFIG_HANDEDNESS); } | ||
| 207 | /** \brief eeconfig update split handedness | ||
| 208 | * | ||
| 209 | * FIXME: needs doc | ||
| 210 | */ | ||
| 211 | void eeconfig_update_handedness(bool val) { eeprom_update_byte(EECONFIG_HANDEDNESS, !!val); } | ||
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h deleted file mode 100644 index a88071729..000000000 --- a/tmk_core/common/eeconfig.h +++ /dev/null | |||
| @@ -1,113 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <stdint.h> | ||
| 21 | #include <stdbool.h> | ||
| 22 | |||
| 23 | #ifndef EECONFIG_MAGIC_NUMBER | ||
| 24 | # define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEEA // When changing, decrement this value to avoid future re-init issues | ||
| 25 | #endif | ||
| 26 | #define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF | ||
| 27 | |||
| 28 | /* EEPROM parameter address */ | ||
| 29 | #define EECONFIG_MAGIC (uint16_t *)0 | ||
| 30 | #define EECONFIG_DEBUG (uint8_t *)2 | ||
| 31 | #define EECONFIG_DEFAULT_LAYER (uint8_t *)3 | ||
| 32 | #define EECONFIG_KEYMAP (uint8_t *)4 | ||
| 33 | #define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5 | ||
| 34 | #define EECONFIG_BACKLIGHT (uint8_t *)6 | ||
| 35 | #define EECONFIG_AUDIO (uint8_t *)7 | ||
| 36 | #define EECONFIG_RGBLIGHT (uint32_t *)8 | ||
| 37 | #define EECONFIG_UNICODEMODE (uint8_t *)12 | ||
| 38 | #define EECONFIG_STENOMODE (uint8_t *)13 | ||
| 39 | // EEHANDS for two handed boards | ||
| 40 | #define EECONFIG_HANDEDNESS (uint8_t *)14 | ||
| 41 | #define EECONFIG_KEYBOARD (uint32_t *)15 | ||
| 42 | #define EECONFIG_USER (uint32_t *)19 | ||
| 43 | #define EECONFIG_VELOCIKEY (uint8_t *)23 | ||
| 44 | |||
| 45 | #define EECONFIG_HAPTIC (uint32_t *)24 | ||
| 46 | |||
| 47 | // Mutually exclusive | ||
| 48 | #define EECONFIG_LED_MATRIX (uint32_t *)28 | ||
| 49 | #define EECONFIG_RGB_MATRIX (uint32_t *)28 | ||
| 50 | // Speed & Flags | ||
| 51 | #define EECONFIG_LED_MATRIX_EXTENDED (uint16_t *)32 | ||
| 52 | #define EECONFIG_RGB_MATRIX_EXTENDED (uint16_t *)32 | ||
| 53 | |||
| 54 | // TODO: Combine these into a single word and single block of EEPROM | ||
| 55 | #define EECONFIG_KEYMAP_UPPER_BYTE (uint8_t *)34 | ||
| 56 | // Size of EEPROM being used, other code can refer to this for available EEPROM | ||
| 57 | #define EECONFIG_SIZE 35 | ||
| 58 | /* debug bit */ | ||
| 59 | #define EECONFIG_DEBUG_ENABLE (1 << 0) | ||
| 60 | #define EECONFIG_DEBUG_MATRIX (1 << 1) | ||
| 61 | #define EECONFIG_DEBUG_KEYBOARD (1 << 2) | ||
| 62 | #define EECONFIG_DEBUG_MOUSE (1 << 3) | ||
| 63 | |||
| 64 | /* keyconf bit */ | ||
| 65 | #define EECONFIG_KEYMAP_SWAP_CONTROL_CAPSLOCK (1 << 0) | ||
| 66 | #define EECONFIG_KEYMAP_CAPSLOCK_TO_CONTROL (1 << 1) | ||
| 67 | #define EECONFIG_KEYMAP_SWAP_LALT_LGUI (1 << 2) | ||
| 68 | #define EECONFIG_KEYMAP_SWAP_RALT_RGUI (1 << 3) | ||
| 69 | #define EECONFIG_KEYMAP_NO_GUI (1 << 4) | ||
| 70 | #define EECONFIG_KEYMAP_SWAP_GRAVE_ESC (1 << 5) | ||
| 71 | #define EECONFIG_KEYMAP_SWAP_BACKSLASH_BACKSPACE (1 << 6) | ||
| 72 | #define EECONFIG_KEYMAP_NKRO (1 << 7) | ||
| 73 | |||
| 74 | #define EECONFIG_KEYMAP_LOWER_BYTE EECONFIG_KEYMAP | ||
| 75 | |||
| 76 | bool eeconfig_is_enabled(void); | ||
| 77 | bool eeconfig_is_disabled(void); | ||
| 78 | |||
| 79 | void eeconfig_init(void); | ||
| 80 | void eeconfig_init_quantum(void); | ||
| 81 | void eeconfig_init_kb(void); | ||
| 82 | void eeconfig_init_user(void); | ||
| 83 | |||
| 84 | void eeconfig_enable(void); | ||
| 85 | |||
| 86 | void eeconfig_disable(void); | ||
| 87 | |||
| 88 | uint8_t eeconfig_read_debug(void); | ||
| 89 | void eeconfig_update_debug(uint8_t val); | ||
| 90 | |||
| 91 | uint8_t eeconfig_read_default_layer(void); | ||
| 92 | void eeconfig_update_default_layer(uint8_t val); | ||
| 93 | |||
| 94 | uint16_t eeconfig_read_keymap(void); | ||
| 95 | void eeconfig_update_keymap(uint16_t val); | ||
| 96 | |||
| 97 | #ifdef AUDIO_ENABLE | ||
| 98 | uint8_t eeconfig_read_audio(void); | ||
| 99 | void eeconfig_update_audio(uint8_t val); | ||
| 100 | #endif | ||
| 101 | |||
| 102 | uint32_t eeconfig_read_kb(void); | ||
| 103 | void eeconfig_update_kb(uint32_t val); | ||
| 104 | uint32_t eeconfig_read_user(void); | ||
| 105 | void eeconfig_update_user(uint32_t val); | ||
| 106 | |||
| 107 | #ifdef HAPTIC_ENABLE | ||
| 108 | uint32_t eeconfig_read_haptic(void); | ||
| 109 | void eeconfig_update_haptic(uint32_t val); | ||
| 110 | #endif | ||
| 111 | |||
| 112 | bool eeconfig_read_handedness(void); | ||
| 113 | void eeconfig_update_handedness(bool val); | ||
diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c index e7d92cfac..f0c396b18 100644 --- a/tmk_core/common/host.c +++ b/tmk_core/common/host.c | |||
| @@ -17,10 +17,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 17 | 17 | ||
| 18 | #include <stdint.h> | 18 | #include <stdint.h> |
| 19 | //#include <avr/interrupt.h> | 19 | //#include <avr/interrupt.h> |
| 20 | #include "keyboard.h" | ||
| 20 | #include "keycode.h" | 21 | #include "keycode.h" |
| 21 | #include "host.h" | 22 | #include "host.h" |
| 22 | #include "util.h" | 23 | #include "util.h" |
| 23 | #include "debug.h" | 24 | #include "debug.h" |
| 25 | #include "digitizer.h" | ||
| 24 | 26 | ||
| 25 | #ifdef NKRO_ENABLE | 27 | #ifdef NKRO_ENABLE |
| 26 | # include "keycode_config.h" | 28 | # include "keycode_config.h" |
| @@ -35,15 +37,20 @@ void host_set_driver(host_driver_t *d) { driver = d; } | |||
| 35 | 37 | ||
| 36 | host_driver_t *host_get_driver(void) { return driver; } | 38 | host_driver_t *host_get_driver(void) { return driver; } |
| 37 | 39 | ||
| 40 | #ifdef SPLIT_KEYBOARD | ||
| 41 | uint8_t split_led_state = 0; | ||
| 42 | void set_split_host_keyboard_leds(uint8_t led_state) { split_led_state = led_state; } | ||
| 43 | #endif | ||
| 44 | |||
| 38 | uint8_t host_keyboard_leds(void) { | 45 | uint8_t host_keyboard_leds(void) { |
| 46 | #ifdef SPLIT_KEYBOARD | ||
| 47 | if (!is_keyboard_master()) return split_led_state; | ||
| 48 | #endif | ||
| 39 | if (!driver) return 0; | 49 | if (!driver) return 0; |
| 40 | return (*driver->keyboard_leds)(); | 50 | return (*driver->keyboard_leds)(); |
| 41 | } | 51 | } |
| 42 | 52 | ||
| 43 | led_t host_keyboard_led_state(void) { | 53 | led_t host_keyboard_led_state(void) { return (led_t)host_keyboard_leds(); } |
| 44 | if (!driver) return (led_t){0}; | ||
| 45 | return (led_t)((*driver->keyboard_leds)()); | ||
| 46 | } | ||
| 47 | 54 | ||
| 48 | /* send report */ | 55 | /* send report */ |
| 49 | void host_keyboard_send(report_keyboard_t *report) { | 56 | void host_keyboard_send(report_keyboard_t *report) { |
| @@ -97,6 +104,24 @@ void host_consumer_send(uint16_t report) { | |||
| 97 | (*driver->send_consumer)(report); | 104 | (*driver->send_consumer)(report); |
| 98 | } | 105 | } |
| 99 | 106 | ||
| 107 | void host_digitizer_send(digitizer_t *digitizer) { | ||
| 108 | if (!driver) return; | ||
| 109 | |||
| 110 | report_digitizer_t report = { | ||
| 111 | #ifdef DIGITIZER_SHARED_EP | ||
| 112 | .report_id = REPORT_ID_DIGITIZER, | ||
| 113 | #endif | ||
| 114 | .tip = digitizer->tipswitch & 0x1, | ||
| 115 | .inrange = digitizer->inrange & 0x1, | ||
| 116 | .x = (uint16_t)(digitizer->x * 0x7FFF), | ||
| 117 | .y = (uint16_t)(digitizer->y * 0x7FFF), | ||
| 118 | }; | ||
| 119 | |||
| 120 | send_digitizer(&report); | ||
| 121 | } | ||
| 122 | |||
| 123 | __attribute__((weak)) void send_digitizer(report_digitizer_t *report) {} | ||
| 124 | |||
| 100 | uint16_t host_last_system_report(void) { return last_system_report; } | 125 | uint16_t host_last_system_report(void) { return last_system_report; } |
| 101 | 126 | ||
| 102 | uint16_t host_last_consumer_report(void) { return last_consumer_report; } | 127 | uint16_t host_last_consumer_report(void) { return last_consumer_report; } |
diff --git a/tmk_core/common/host_driver.h b/tmk_core/common/host_driver.h index f34a22053..2aebca043 100644 --- a/tmk_core/common/host_driver.h +++ b/tmk_core/common/host_driver.h | |||
| @@ -30,3 +30,5 @@ typedef struct { | |||
| 30 | void (*send_system)(uint16_t); | 30 | void (*send_system)(uint16_t); |
| 31 | void (*send_consumer)(uint16_t); | 31 | void (*send_consumer)(uint16_t); |
| 32 | } host_driver_t; | 32 | } host_driver_t; |
| 33 | |||
| 34 | void send_digitizer(report_digitizer_t *report); \ No newline at end of file | ||
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c deleted file mode 100644 index 3d6092e71..000000000 --- a/tmk_core/common/keyboard.c +++ /dev/null | |||
| @@ -1,534 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011, 2012, 2013 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <stdint.h> | ||
| 19 | #include "keyboard.h" | ||
| 20 | #include "matrix.h" | ||
| 21 | #include "keymap.h" | ||
| 22 | #include "host.h" | ||
| 23 | #include "led.h" | ||
| 24 | #include "keycode.h" | ||
| 25 | #include "timer.h" | ||
| 26 | #include "sync_timer.h" | ||
| 27 | #include "print.h" | ||
| 28 | #include "debug.h" | ||
| 29 | #include "command.h" | ||
| 30 | #include "util.h" | ||
| 31 | #include "sendchar.h" | ||
| 32 | #include "eeconfig.h" | ||
| 33 | #include "action_layer.h" | ||
| 34 | #ifdef BACKLIGHT_ENABLE | ||
| 35 | # include "backlight.h" | ||
| 36 | #endif | ||
| 37 | #ifdef MOUSEKEY_ENABLE | ||
| 38 | # include "mousekey.h" | ||
| 39 | #endif | ||
| 40 | #ifdef PS2_MOUSE_ENABLE | ||
| 41 | # include "ps2_mouse.h" | ||
| 42 | #endif | ||
| 43 | #ifdef SERIAL_MOUSE_ENABLE | ||
| 44 | # include "serial_mouse.h" | ||
| 45 | #endif | ||
| 46 | #ifdef ADB_MOUSE_ENABLE | ||
| 47 | # include "adb.h" | ||
| 48 | #endif | ||
| 49 | #ifdef RGBLIGHT_ENABLE | ||
| 50 | # include "rgblight.h" | ||
| 51 | #endif | ||
| 52 | #ifdef LED_MATRIX_ENABLE | ||
| 53 | # include "led_matrix.h" | ||
| 54 | #endif | ||
| 55 | #ifdef RGB_MATRIX_ENABLE | ||
| 56 | # include "rgb_matrix.h" | ||
| 57 | #endif | ||
| 58 | #ifdef ENCODER_ENABLE | ||
| 59 | # include "encoder.h" | ||
| 60 | #endif | ||
| 61 | #ifdef STENO_ENABLE | ||
| 62 | # include "process_steno.h" | ||
| 63 | #endif | ||
| 64 | #ifdef SERIAL_LINK_ENABLE | ||
| 65 | # include "serial_link/system/serial_link.h" | ||
| 66 | #endif | ||
| 67 | #ifdef VISUALIZER_ENABLE | ||
| 68 | # include "visualizer/visualizer.h" | ||
| 69 | #endif | ||
| 70 | #ifdef POINTING_DEVICE_ENABLE | ||
| 71 | # include "pointing_device.h" | ||
| 72 | #endif | ||
| 73 | #ifdef MIDI_ENABLE | ||
| 74 | # include "process_midi.h" | ||
| 75 | #endif | ||
| 76 | #ifdef JOYSTICK_ENABLE | ||
| 77 | # include "process_joystick.h" | ||
| 78 | #endif | ||
| 79 | #ifdef HD44780_ENABLE | ||
| 80 | # include "hd44780.h" | ||
| 81 | #endif | ||
| 82 | #ifdef QWIIC_ENABLE | ||
| 83 | # include "qwiic.h" | ||
| 84 | #endif | ||
| 85 | #ifdef OLED_DRIVER_ENABLE | ||
| 86 | # include "oled_driver.h" | ||
| 87 | #endif | ||
| 88 | #ifdef VELOCIKEY_ENABLE | ||
| 89 | # include "velocikey.h" | ||
| 90 | #endif | ||
| 91 | #ifdef VIA_ENABLE | ||
| 92 | # include "via.h" | ||
| 93 | #endif | ||
| 94 | #ifdef DIP_SWITCH_ENABLE | ||
| 95 | # include "dip_switch.h" | ||
| 96 | #endif | ||
| 97 | #ifdef STM32_EEPROM_ENABLE | ||
| 98 | # include "eeprom_stm32.h" | ||
| 99 | #endif | ||
| 100 | #ifdef EEPROM_DRIVER | ||
| 101 | # include "eeprom_driver.h" | ||
| 102 | #endif | ||
| 103 | |||
| 104 | static uint32_t last_input_modification_time = 0; | ||
| 105 | uint32_t last_input_activity_time(void) { return last_input_modification_time; } | ||
| 106 | uint32_t last_input_activity_elapsed(void) { return timer_elapsed32(last_input_modification_time); } | ||
| 107 | |||
| 108 | static uint32_t last_matrix_modification_time = 0; | ||
| 109 | uint32_t last_matrix_activity_time(void) { return last_matrix_modification_time; } | ||
| 110 | uint32_t last_matrix_activity_elapsed(void) { return timer_elapsed32(last_matrix_modification_time); } | ||
| 111 | void last_matrix_activity_trigger(void) { last_matrix_modification_time = last_input_modification_time = timer_read32(); } | ||
| 112 | |||
| 113 | static uint32_t last_encoder_modification_time = 0; | ||
| 114 | uint32_t last_encoder_activity_time(void) { return last_encoder_modification_time; } | ||
| 115 | uint32_t last_encoder_activity_elapsed(void) { return timer_elapsed32(last_encoder_modification_time); } | ||
| 116 | void last_encoder_activity_trigger(void) { last_encoder_modification_time = last_input_modification_time = timer_read32(); } | ||
| 117 | |||
| 118 | // Only enable this if console is enabled to print to | ||
| 119 | #if defined(DEBUG_MATRIX_SCAN_RATE) | ||
| 120 | static uint32_t matrix_timer = 0; | ||
| 121 | static uint32_t matrix_scan_count = 0; | ||
| 122 | static uint32_t last_matrix_scan_count = 0; | ||
| 123 | |||
| 124 | void matrix_scan_perf_task(void) { | ||
| 125 | matrix_scan_count++; | ||
| 126 | |||
| 127 | uint32_t timer_now = timer_read32(); | ||
| 128 | if (TIMER_DIFF_32(timer_now, matrix_timer) > 1000) { | ||
| 129 | # if defined(CONSOLE_ENABLE) | ||
| 130 | dprintf("matrix scan frequency: %lu\n", matrix_scan_count); | ||
| 131 | # endif | ||
| 132 | last_matrix_scan_count = matrix_scan_count; | ||
| 133 | matrix_timer = timer_now; | ||
| 134 | matrix_scan_count = 0; | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | uint32_t get_matrix_scan_rate(void) { return last_matrix_scan_count; } | ||
| 139 | #else | ||
| 140 | # define matrix_scan_perf_task() | ||
| 141 | #endif | ||
| 142 | |||
| 143 | #ifdef MATRIX_HAS_GHOST | ||
| 144 | extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; | ||
| 145 | static matrix_row_t get_real_keys(uint8_t row, matrix_row_t rowdata) { | ||
| 146 | matrix_row_t out = 0; | ||
| 147 | for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||
| 148 | // read each key in the row data and check if the keymap defines it as a real key | ||
| 149 | if (pgm_read_byte(&keymaps[0][row][col]) && (rowdata & (1 << col))) { | ||
| 150 | // this creates new row data, if a key is defined in the keymap, it will be set here | ||
| 151 | out |= 1 << col; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | return out; | ||
| 155 | } | ||
| 156 | |||
| 157 | static inline bool popcount_more_than_one(matrix_row_t rowdata) { | ||
| 158 | rowdata &= rowdata - 1; // if there are less than two bits (keys) set, rowdata will become zero | ||
| 159 | return rowdata; | ||
| 160 | } | ||
| 161 | |||
| 162 | static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) { | ||
| 163 | /* No ghost exists when less than 2 keys are down on the row. | ||
| 164 | If there are "active" blanks in the matrix, the key can't be pressed by the user, | ||
| 165 | there is no doubt as to which keys are really being pressed. | ||
| 166 | The ghosts will be ignored, they are KC_NO. */ | ||
| 167 | rowdata = get_real_keys(row, rowdata); | ||
| 168 | if ((popcount_more_than_one(rowdata)) == 0) { | ||
| 169 | return false; | ||
| 170 | } | ||
| 171 | /* Ghost occurs when the row shares a column line with other row, | ||
| 172 | and two columns are read on each row. Blanks in the matrix don't matter, | ||
| 173 | so they are filtered out. | ||
| 174 | If there are two or more real keys pressed and they match columns with | ||
| 175 | at least two of another row's real keys, the row will be ignored. Keep in mind, | ||
| 176 | we are checking one row at a time, not all of them at once. | ||
| 177 | */ | ||
| 178 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
| 179 | if (i != row && popcount_more_than_one(get_real_keys(i, matrix_get_row(i)) & rowdata)) { | ||
| 180 | return true; | ||
| 181 | } | ||
| 182 | } | ||
| 183 | return false; | ||
| 184 | } | ||
| 185 | |||
| 186 | #endif | ||
| 187 | |||
| 188 | void disable_jtag(void) { | ||
| 189 | // To use PF4-7 (PC2-5 on ATmega32A), disable JTAG by writing JTD bit twice within four cycles. | ||
| 190 | #if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) | ||
| 191 | MCUCR |= _BV(JTD); | ||
| 192 | MCUCR |= _BV(JTD); | ||
| 193 | #elif defined(__AVR_ATmega32A__) | ||
| 194 | MCUCSR |= _BV(JTD); | ||
| 195 | MCUCSR |= _BV(JTD); | ||
| 196 | #endif | ||
| 197 | } | ||
| 198 | |||
| 199 | /** \brief matrix_setup | ||
| 200 | * | ||
| 201 | * FIXME: needs doc | ||
| 202 | */ | ||
| 203 | __attribute__((weak)) void matrix_setup(void) {} | ||
| 204 | |||
| 205 | /** \brief keyboard_pre_init_user | ||
| 206 | * | ||
| 207 | * FIXME: needs doc | ||
| 208 | */ | ||
| 209 | __attribute__((weak)) void keyboard_pre_init_user(void) {} | ||
| 210 | |||
| 211 | /** \brief keyboard_pre_init_kb | ||
| 212 | * | ||
| 213 | * FIXME: needs doc | ||
| 214 | */ | ||
| 215 | __attribute__((weak)) void keyboard_pre_init_kb(void) { keyboard_pre_init_user(); } | ||
| 216 | |||
| 217 | /** \brief keyboard_post_init_user | ||
| 218 | * | ||
| 219 | * FIXME: needs doc | ||
| 220 | */ | ||
| 221 | |||
| 222 | __attribute__((weak)) void keyboard_post_init_user() {} | ||
| 223 | |||
| 224 | /** \brief keyboard_post_init_kb | ||
| 225 | * | ||
| 226 | * FIXME: needs doc | ||
| 227 | */ | ||
| 228 | |||
| 229 | __attribute__((weak)) void keyboard_post_init_kb(void) { keyboard_post_init_user(); } | ||
| 230 | |||
| 231 | /** \brief keyboard_setup | ||
| 232 | * | ||
| 233 | * FIXME: needs doc | ||
| 234 | */ | ||
| 235 | void keyboard_setup(void) { | ||
| 236 | #ifndef NO_JTAG_DISABLE | ||
| 237 | disable_jtag(); | ||
| 238 | #endif | ||
| 239 | print_set_sendchar(sendchar); | ||
| 240 | #ifdef STM32_EEPROM_ENABLE | ||
| 241 | EEPROM_Init(); | ||
| 242 | #endif | ||
| 243 | #ifdef EEPROM_DRIVER | ||
| 244 | eeprom_driver_init(); | ||
| 245 | #endif | ||
| 246 | matrix_setup(); | ||
| 247 | keyboard_pre_init_kb(); | ||
| 248 | } | ||
| 249 | |||
| 250 | /** \brief is_keyboard_master | ||
| 251 | * | ||
| 252 | * FIXME: needs doc | ||
| 253 | */ | ||
| 254 | __attribute__((weak)) bool is_keyboard_master(void) { return true; } | ||
| 255 | |||
| 256 | /** \brief is_keyboard_left | ||
| 257 | * | ||
| 258 | * FIXME: needs doc | ||
| 259 | */ | ||
| 260 | __attribute__((weak)) bool is_keyboard_left(void) { return true; } | ||
| 261 | |||
| 262 | /** \brief should_process_keypress | ||
| 263 | * | ||
| 264 | * Override this function if you have a condition where keypresses processing should change: | ||
| 265 | * - splits where the slave side needs to process for rgb/oled functionality | ||
| 266 | */ | ||
| 267 | __attribute__((weak)) bool should_process_keypress(void) { return is_keyboard_master(); } | ||
| 268 | |||
| 269 | /** \brief housekeeping_task_kb | ||
| 270 | * | ||
| 271 | * Override this function if you have a need to execute code for every keyboard main loop iteration. | ||
| 272 | * This is specific to keyboard-level functionality. | ||
| 273 | */ | ||
| 274 | __attribute__((weak)) void housekeeping_task_kb(void) {} | ||
| 275 | |||
| 276 | /** \brief housekeeping_task_user | ||
| 277 | * | ||
| 278 | * Override this function if you have a need to execute code for every keyboard main loop iteration. | ||
| 279 | * This is specific to user/keymap-level functionality. | ||
| 280 | */ | ||
| 281 | __attribute__((weak)) void housekeeping_task_user(void) {} | ||
| 282 | |||
| 283 | /** \brief housekeeping_task | ||
| 284 | * | ||
| 285 | * Invokes hooks for executing code after QMK is done after each loop iteration. | ||
| 286 | */ | ||
| 287 | void housekeeping_task(void) { | ||
| 288 | housekeeping_task_kb(); | ||
| 289 | housekeeping_task_user(); | ||
| 290 | } | ||
| 291 | |||
| 292 | /** \brief keyboard_init | ||
| 293 | * | ||
| 294 | * FIXME: needs doc | ||
| 295 | */ | ||
| 296 | void keyboard_init(void) { | ||
| 297 | timer_init(); | ||
| 298 | sync_timer_init(); | ||
| 299 | matrix_init(); | ||
| 300 | #ifdef VIA_ENABLE | ||
| 301 | via_init(); | ||
| 302 | #endif | ||
| 303 | #ifdef QWIIC_ENABLE | ||
| 304 | qwiic_init(); | ||
| 305 | #endif | ||
| 306 | #ifdef OLED_DRIVER_ENABLE | ||
| 307 | oled_init(OLED_ROTATION_0); | ||
| 308 | #endif | ||
| 309 | #ifdef PS2_MOUSE_ENABLE | ||
| 310 | ps2_mouse_init(); | ||
| 311 | #endif | ||
| 312 | #ifdef SERIAL_MOUSE_ENABLE | ||
| 313 | serial_mouse_init(); | ||
| 314 | #endif | ||
| 315 | #ifdef ADB_MOUSE_ENABLE | ||
| 316 | adb_mouse_init(); | ||
| 317 | #endif | ||
| 318 | #ifdef BACKLIGHT_ENABLE | ||
| 319 | backlight_init(); | ||
| 320 | #endif | ||
| 321 | #ifdef RGBLIGHT_ENABLE | ||
| 322 | rgblight_init(); | ||
| 323 | #endif | ||
| 324 | #ifdef ENCODER_ENABLE | ||
| 325 | encoder_init(); | ||
| 326 | #endif | ||
| 327 | #ifdef STENO_ENABLE | ||
| 328 | steno_init(); | ||
| 329 | #endif | ||
| 330 | #ifdef POINTING_DEVICE_ENABLE | ||
| 331 | pointing_device_init(); | ||
| 332 | #endif | ||
| 333 | #if defined(NKRO_ENABLE) && defined(FORCE_NKRO) | ||
| 334 | keymap_config.nkro = 1; | ||
| 335 | eeconfig_update_keymap(keymap_config.raw); | ||
| 336 | #endif | ||
| 337 | #ifdef DIP_SWITCH_ENABLE | ||
| 338 | dip_switch_init(); | ||
| 339 | #endif | ||
| 340 | |||
| 341 | #if defined(DEBUG_MATRIX_SCAN_RATE) && defined(CONSOLE_ENABLE) | ||
| 342 | debug_enable = true; | ||
| 343 | #endif | ||
| 344 | |||
| 345 | keyboard_post_init_kb(); /* Always keep this last */ | ||
| 346 | } | ||
| 347 | |||
| 348 | /** \brief key_event_task | ||
| 349 | * | ||
| 350 | * This function is responsible for calling into other systems when they need to respond to electrical switch press events. | ||
| 351 | * This is differnet than keycode events as no layer processing, or filtering occurs. | ||
| 352 | */ | ||
| 353 | void switch_events(uint8_t row, uint8_t col, bool pressed) { | ||
| 354 | #if defined(LED_MATRIX_ENABLE) | ||
| 355 | process_led_matrix(row, col, pressed); | ||
| 356 | #endif | ||
| 357 | #if defined(RGB_MATRIX_ENABLE) | ||
| 358 | process_rgb_matrix(row, col, pressed); | ||
| 359 | #endif | ||
| 360 | } | ||
| 361 | |||
| 362 | /** \brief Keyboard task: Do keyboard routine jobs | ||
| 363 | * | ||
| 364 | * Do routine keyboard jobs: | ||
| 365 | * | ||
| 366 | * * scan matrix | ||
| 367 | * * handle mouse movements | ||
| 368 | * * run visualizer code | ||
| 369 | * * handle midi commands | ||
| 370 | * * light LEDs | ||
| 371 | * | ||
| 372 | * This is repeatedly called as fast as possible. | ||
| 373 | */ | ||
| 374 | void keyboard_task(void) { | ||
| 375 | static matrix_row_t matrix_prev[MATRIX_ROWS]; | ||
| 376 | static uint8_t led_status = 0; | ||
| 377 | matrix_row_t matrix_row = 0; | ||
| 378 | matrix_row_t matrix_change = 0; | ||
| 379 | #ifdef QMK_KEYS_PER_SCAN | ||
| 380 | uint8_t keys_processed = 0; | ||
| 381 | #endif | ||
| 382 | #ifdef ENCODER_ENABLE | ||
| 383 | bool encoders_changed = false; | ||
| 384 | #endif | ||
| 385 | |||
| 386 | uint8_t matrix_changed = matrix_scan(); | ||
| 387 | if (matrix_changed) last_matrix_activity_trigger(); | ||
| 388 | |||
| 389 | for (uint8_t r = 0; r < MATRIX_ROWS; r++) { | ||
| 390 | matrix_row = matrix_get_row(r); | ||
| 391 | matrix_change = matrix_row ^ matrix_prev[r]; | ||
| 392 | if (matrix_change) { | ||
| 393 | #ifdef MATRIX_HAS_GHOST | ||
| 394 | if (has_ghost_in_row(r, matrix_row)) { | ||
| 395 | continue; | ||
| 396 | } | ||
| 397 | #endif | ||
| 398 | if (debug_matrix) matrix_print(); | ||
| 399 | matrix_row_t col_mask = 1; | ||
| 400 | for (uint8_t c = 0; c < MATRIX_COLS; c++, col_mask <<= 1) { | ||
| 401 | if (matrix_change & col_mask) { | ||
| 402 | if (should_process_keypress()) { | ||
| 403 | action_exec((keyevent_t){ | ||
| 404 | .key = (keypos_t){.row = r, .col = c}, .pressed = (matrix_row & col_mask), .time = (timer_read() | 1) /* time should not be 0 */ | ||
| 405 | }); | ||
| 406 | } | ||
| 407 | // record a processed key | ||
| 408 | matrix_prev[r] ^= col_mask; | ||
| 409 | |||
| 410 | switch_events(r, c, (matrix_row & col_mask)); | ||
| 411 | |||
| 412 | #ifdef QMK_KEYS_PER_SCAN | ||
| 413 | // only jump out if we have processed "enough" keys. | ||
| 414 | if (++keys_processed >= QMK_KEYS_PER_SCAN) | ||
| 415 | #endif | ||
| 416 | // process a key per task call | ||
| 417 | goto MATRIX_LOOP_END; | ||
| 418 | } | ||
| 419 | } | ||
| 420 | } | ||
| 421 | } | ||
| 422 | // call with pseudo tick event when no real key event. | ||
| 423 | #ifdef QMK_KEYS_PER_SCAN | ||
| 424 | // we can get here with some keys processed now. | ||
| 425 | if (!keys_processed) | ||
| 426 | #endif | ||
| 427 | action_exec(TICK); | ||
| 428 | |||
| 429 | MATRIX_LOOP_END: | ||
| 430 | |||
| 431 | #ifdef DEBUG_MATRIX_SCAN_RATE | ||
| 432 | matrix_scan_perf_task(); | ||
| 433 | #endif | ||
| 434 | |||
| 435 | #if defined(RGBLIGHT_ENABLE) | ||
| 436 | rgblight_task(); | ||
| 437 | #endif | ||
| 438 | |||
| 439 | #ifdef LED_MATRIX_ENABLE | ||
| 440 | led_matrix_task(); | ||
| 441 | #endif | ||
| 442 | #ifdef RGB_MATRIX_ENABLE | ||
| 443 | rgb_matrix_task(); | ||
| 444 | #endif | ||
| 445 | |||
| 446 | #if defined(BACKLIGHT_ENABLE) | ||
| 447 | # if defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS) | ||
| 448 | backlight_task(); | ||
| 449 | # endif | ||
| 450 | #endif | ||
| 451 | |||
| 452 | #ifdef ENCODER_ENABLE | ||
| 453 | encoders_changed = encoder_read(); | ||
| 454 | if (encoders_changed) last_encoder_activity_trigger(); | ||
| 455 | #endif | ||
| 456 | |||
| 457 | #ifdef QWIIC_ENABLE | ||
| 458 | qwiic_task(); | ||
| 459 | #endif | ||
| 460 | |||
| 461 | #ifdef OLED_DRIVER_ENABLE | ||
| 462 | oled_task(); | ||
| 463 | # ifndef OLED_DISABLE_TIMEOUT | ||
| 464 | // Wake up oled if user is using those fabulous keys or spinning those encoders! | ||
| 465 | # ifdef ENCODER_ENABLE | ||
| 466 | if (matrix_changed || encoders_changed) oled_on(); | ||
| 467 | # else | ||
| 468 | if (matrix_changed) oled_on(); | ||
| 469 | # endif | ||
| 470 | # endif | ||
| 471 | #endif | ||
| 472 | |||
| 473 | #ifdef MOUSEKEY_ENABLE | ||
| 474 | // mousekey repeat & acceleration | ||
| 475 | mousekey_task(); | ||
| 476 | #endif | ||
| 477 | |||
| 478 | #ifdef PS2_MOUSE_ENABLE | ||
| 479 | ps2_mouse_task(); | ||
| 480 | #endif | ||
| 481 | |||
| 482 | #ifdef SERIAL_MOUSE_ENABLE | ||
| 483 | serial_mouse_task(); | ||
| 484 | #endif | ||
| 485 | |||
| 486 | #ifdef ADB_MOUSE_ENABLE | ||
| 487 | adb_mouse_task(); | ||
| 488 | #endif | ||
| 489 | |||
| 490 | #ifdef SERIAL_LINK_ENABLE | ||
| 491 | serial_link_update(); | ||
| 492 | #endif | ||
| 493 | |||
| 494 | #ifdef VISUALIZER_ENABLE | ||
| 495 | visualizer_update(default_layer_state, layer_state, visualizer_get_mods(), host_keyboard_leds()); | ||
| 496 | #endif | ||
| 497 | |||
| 498 | #ifdef POINTING_DEVICE_ENABLE | ||
| 499 | pointing_device_task(); | ||
| 500 | #endif | ||
| 501 | |||
| 502 | #ifdef MIDI_ENABLE | ||
| 503 | midi_task(); | ||
| 504 | #endif | ||
| 505 | |||
| 506 | #ifdef VELOCIKEY_ENABLE | ||
| 507 | if (velocikey_enabled()) { | ||
| 508 | velocikey_decelerate(); | ||
| 509 | } | ||
| 510 | #endif | ||
| 511 | |||
| 512 | #ifdef JOYSTICK_ENABLE | ||
| 513 | joystick_task(); | ||
| 514 | #endif | ||
| 515 | |||
| 516 | // update LED | ||
| 517 | if (led_status != host_keyboard_leds()) { | ||
| 518 | led_status = host_keyboard_leds(); | ||
| 519 | keyboard_set_leds(led_status); | ||
| 520 | } | ||
| 521 | } | ||
| 522 | |||
| 523 | /** \brief keyboard set leds | ||
| 524 | * | ||
| 525 | * FIXME: needs doc | ||
| 526 | */ | ||
| 527 | void keyboard_set_leds(uint8_t leds) { | ||
| 528 | if (debug_keyboard) { | ||
| 529 | debug("keyboard_set_led: "); | ||
| 530 | debug_hex8(leds); | ||
| 531 | debug("\n"); | ||
| 532 | } | ||
| 533 | led_set(leds); | ||
| 534 | } | ||
diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h deleted file mode 100644 index 08f4e84f9..000000000 --- a/tmk_core/common/keyboard.h +++ /dev/null | |||
| @@ -1,90 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011,2012,2013 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <stdbool.h> | ||
| 21 | #include <stdint.h> | ||
| 22 | |||
| 23 | #ifdef __cplusplus | ||
| 24 | extern "C" { | ||
| 25 | #endif | ||
| 26 | |||
| 27 | /* key matrix position */ | ||
| 28 | typedef struct { | ||
| 29 | uint8_t col; | ||
| 30 | uint8_t row; | ||
| 31 | } keypos_t; | ||
| 32 | |||
| 33 | /* key event */ | ||
| 34 | typedef struct { | ||
| 35 | keypos_t key; | ||
| 36 | bool pressed; | ||
| 37 | uint16_t time; | ||
| 38 | } keyevent_t; | ||
| 39 | |||
| 40 | /* equivalent test of keypos_t */ | ||
| 41 | #define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col) | ||
| 42 | |||
| 43 | /* Rules for No Event: | ||
| 44 | * 1) (time == 0) to handle (keyevent_t){} as empty event | ||
| 45 | * 2) Matrix(255, 255) to make TICK event available | ||
| 46 | */ | ||
| 47 | static inline bool IS_NOEVENT(keyevent_t event) { return event.time == 0 || (event.key.row == 255 && event.key.col == 255); } | ||
| 48 | static inline bool IS_PRESSED(keyevent_t event) { return (!IS_NOEVENT(event) && event.pressed); } | ||
| 49 | static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) && !event.pressed); } | ||
| 50 | |||
| 51 | /* Tick event */ | ||
| 52 | #define TICK \ | ||
| 53 | (keyevent_t) { .key = (keypos_t){.row = 255, .col = 255}, .pressed = false, .time = (timer_read() | 1) } | ||
| 54 | |||
| 55 | /* it runs once at early stage of startup before keyboard_init. */ | ||
| 56 | void keyboard_setup(void); | ||
| 57 | /* it runs once after initializing host side protocol, debug and MCU peripherals. */ | ||
| 58 | void keyboard_init(void); | ||
| 59 | /* it runs repeatedly in main loop */ | ||
| 60 | void keyboard_task(void); | ||
| 61 | /* it runs when host LED status is updated */ | ||
| 62 | void keyboard_set_leds(uint8_t leds); | ||
| 63 | /* it runs whenever code has to behave differently on a slave */ | ||
| 64 | bool is_keyboard_master(void); | ||
| 65 | /* it runs whenever code has to behave differently on left vs right split */ | ||
| 66 | bool is_keyboard_left(void); | ||
| 67 | |||
| 68 | void keyboard_pre_init_kb(void); | ||
| 69 | void keyboard_pre_init_user(void); | ||
| 70 | void keyboard_post_init_kb(void); | ||
| 71 | void keyboard_post_init_user(void); | ||
| 72 | |||
| 73 | void housekeeping_task(void); // To be executed by the main loop in each backend TMK protocol | ||
| 74 | void housekeeping_task_kb(void); // To be overridden by keyboard-level code | ||
| 75 | void housekeeping_task_user(void); // To be overridden by user/keymap-level code | ||
| 76 | |||
| 77 | uint32_t last_input_activity_time(void); // Timestamp of the last matrix or encoder activity | ||
| 78 | uint32_t last_input_activity_elapsed(void); // Number of milliseconds since the last matrix or encoder activity | ||
| 79 | |||
| 80 | uint32_t last_matrix_activity_time(void); // Timestamp of the last matrix activity | ||
| 81 | uint32_t last_matrix_activity_elapsed(void); // Number of milliseconds since the last matrix activity | ||
| 82 | |||
| 83 | uint32_t last_encoder_activity_time(void); // Timestamp of the last encoder activity | ||
| 84 | uint32_t last_encoder_activity_elapsed(void); // Number of milliseconds since the last encoder activity | ||
| 85 | |||
| 86 | uint32_t get_matrix_scan_rate(void); | ||
| 87 | |||
| 88 | #ifdef __cplusplus | ||
| 89 | } | ||
| 90 | #endif | ||
diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h deleted file mode 100644 index 8facabd81..000000000 --- a/tmk_core/common/keycode.h +++ /dev/null | |||
| @@ -1,560 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011,2012 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* | ||
| 19 | * Keycodes based on HID Keyboard/Keypad Usage Page (0x07) plus media keys from Generic Desktop Page (0x01) and Consumer Page (0x0C) | ||
| 20 | * | ||
| 21 | * See https://web.archive.org/web/20060218214400/http://www.usb.org/developers/devclass_docs/Hut1_12.pdf | ||
| 22 | * or http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (older) | ||
| 23 | */ | ||
| 24 | |||
| 25 | #pragma once | ||
| 26 | |||
| 27 | /* FIXME: Add doxygen comments here */ | ||
| 28 | |||
| 29 | #define IS_ERROR(code) (KC_ROLL_OVER <= (code) && (code) <= KC_UNDEFINED) | ||
| 30 | #define IS_ANY(code) (KC_A <= (code) && (code) <= 0xFF) | ||
| 31 | #define IS_KEY(code) (KC_A <= (code) && (code) <= KC_EXSEL) | ||
| 32 | #define IS_MOD(code) (KC_LCTRL <= (code) && (code) <= KC_RGUI) | ||
| 33 | |||
| 34 | #define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF)) | ||
| 35 | #define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE) | ||
| 36 | #define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_BRID) | ||
| 37 | |||
| 38 | #define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31) | ||
| 39 | |||
| 40 | #define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2) | ||
| 41 | #define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT) | ||
| 42 | #define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8) | ||
| 43 | #define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT) | ||
| 44 | #define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2) | ||
| 45 | |||
| 46 | #define MOD_BIT(code) (1 << MOD_INDEX(code)) | ||
| 47 | #define MOD_INDEX(code) ((code)&0x07) | ||
| 48 | |||
| 49 | #define MOD_MASK_CTRL (MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RCTRL)) | ||
| 50 | #define MOD_MASK_SHIFT (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) | ||
| 51 | #define MOD_MASK_ALT (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT)) | ||
| 52 | #define MOD_MASK_GUI (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI)) | ||
| 53 | #define MOD_MASK_CS (MOD_MASK_CTRL | MOD_MASK_SHIFT) | ||
| 54 | #define MOD_MASK_CA (MOD_MASK_CTRL | MOD_MASK_ALT) | ||
| 55 | #define MOD_MASK_CG (MOD_MASK_CTRL | MOD_MASK_GUI) | ||
| 56 | #define MOD_MASK_SA (MOD_MASK_SHIFT | MOD_MASK_ALT) | ||
| 57 | #define MOD_MASK_SG (MOD_MASK_SHIFT | MOD_MASK_GUI) | ||
| 58 | #define MOD_MASK_AG (MOD_MASK_ALT | MOD_MASK_GUI) | ||
| 59 | #define MOD_MASK_CSA (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT) | ||
| 60 | #define MOD_MASK_CSG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_GUI) | ||
| 61 | #define MOD_MASK_CAG (MOD_MASK_CTRL | MOD_MASK_ALT | MOD_MASK_GUI) | ||
| 62 | #define MOD_MASK_SAG (MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI) | ||
| 63 | #define MOD_MASK_CSAG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI) | ||
| 64 | |||
| 65 | #define FN_BIT(code) (1 << FN_INDEX(code)) | ||
| 66 | #define FN_INDEX(code) ((code)-KC_FN0) | ||
| 67 | #define FN_MIN KC_FN0 | ||
| 68 | #define FN_MAX KC_FN31 | ||
| 69 | |||
| 70 | /* | ||
| 71 | * Short names for ease of definition of keymap | ||
| 72 | */ | ||
| 73 | /* Transparent */ | ||
| 74 | #define KC_TRANSPARENT 0x01 | ||
| 75 | #define KC_TRNS KC_TRANSPARENT | ||
| 76 | |||
| 77 | /* Punctuation */ | ||
| 78 | #define KC_ENT KC_ENTER | ||
| 79 | #define KC_ESC KC_ESCAPE | ||
| 80 | #define KC_BSPC KC_BSPACE | ||
| 81 | #define KC_SPC KC_SPACE | ||
| 82 | #define KC_MINS KC_MINUS | ||
| 83 | #define KC_EQL KC_EQUAL | ||
| 84 | #define KC_LBRC KC_LBRACKET | ||
| 85 | #define KC_RBRC KC_RBRACKET | ||
| 86 | #define KC_BSLS KC_BSLASH | ||
| 87 | #define KC_NUHS KC_NONUS_HASH | ||
| 88 | #define KC_SCLN KC_SCOLON | ||
| 89 | #define KC_QUOT KC_QUOTE | ||
| 90 | #define KC_GRV KC_GRAVE | ||
| 91 | #define KC_COMM KC_COMMA | ||
| 92 | #define KC_SLSH KC_SLASH | ||
| 93 | #define KC_NUBS KC_NONUS_BSLASH | ||
| 94 | |||
| 95 | /* Lock Keys */ | ||
| 96 | #define KC_CLCK KC_CAPSLOCK | ||
| 97 | #define KC_CAPS KC_CAPSLOCK | ||
| 98 | #define KC_SLCK KC_SCROLLLOCK | ||
| 99 | #define KC_NLCK KC_NUMLOCK | ||
| 100 | #define KC_LCAP KC_LOCKING_CAPS | ||
| 101 | #define KC_LNUM KC_LOCKING_NUM | ||
| 102 | #define KC_LSCR KC_LOCKING_SCROLL | ||
| 103 | |||
| 104 | /* Commands */ | ||
| 105 | #define KC_PSCR KC_PSCREEN | ||
| 106 | #define KC_PAUS KC_PAUSE | ||
| 107 | #define KC_BRK KC_PAUSE | ||
| 108 | #define KC_INS KC_INSERT | ||
| 109 | #define KC_DEL KC_DELETE | ||
| 110 | #define KC_PGDN KC_PGDOWN | ||
| 111 | #define KC_RGHT KC_RIGHT | ||
| 112 | #define KC_APP KC_APPLICATION | ||
| 113 | #define KC_EXEC KC_EXECUTE | ||
| 114 | #define KC_SLCT KC_SELECT | ||
| 115 | #define KC_AGIN KC_AGAIN | ||
| 116 | #define KC_PSTE KC_PASTE | ||
| 117 | #define KC_ERAS KC_ALT_ERASE | ||
| 118 | #define KC_CLR KC_CLEAR | ||
| 119 | |||
| 120 | /* Keypad */ | ||
| 121 | #define KC_PSLS KC_KP_SLASH | ||
| 122 | #define KC_PAST KC_KP_ASTERISK | ||
| 123 | #define KC_PMNS KC_KP_MINUS | ||
| 124 | #define KC_PPLS KC_KP_PLUS | ||
| 125 | #define KC_PENT KC_KP_ENTER | ||
| 126 | #define KC_P1 KC_KP_1 | ||
| 127 | #define KC_P2 KC_KP_2 | ||
| 128 | #define KC_P3 KC_KP_3 | ||
| 129 | #define KC_P4 KC_KP_4 | ||
| 130 | #define KC_P5 KC_KP_5 | ||
| 131 | #define KC_P6 KC_KP_6 | ||
| 132 | #define KC_P7 KC_KP_7 | ||
| 133 | #define KC_P8 KC_KP_8 | ||
| 134 | #define KC_P9 KC_KP_9 | ||
| 135 | #define KC_P0 KC_KP_0 | ||
| 136 | #define KC_PDOT KC_KP_DOT | ||
| 137 | #define KC_PEQL KC_KP_EQUAL | ||
| 138 | #define KC_PCMM KC_KP_COMMA | ||
| 139 | |||
| 140 | /* Japanese specific */ | ||
| 141 | #define KC_ZKHK KC_GRAVE | ||
| 142 | #define KC_RO KC_INT1 | ||
| 143 | #define KC_KANA KC_INT2 | ||
| 144 | #define KC_JYEN KC_INT3 | ||
| 145 | #define KC_HENK KC_INT4 | ||
| 146 | #define KC_MHEN KC_INT5 | ||
| 147 | |||
| 148 | /* Korean specific */ | ||
| 149 | #define KC_HAEN KC_LANG1 | ||
| 150 | #define KC_HANJ KC_LANG2 | ||
| 151 | |||
| 152 | /* Modifiers */ | ||
| 153 | #define KC_LCTL KC_LCTRL | ||
| 154 | #define KC_LSFT KC_LSHIFT | ||
| 155 | #define KC_LOPT KC_LALT | ||
| 156 | #define KC_LCMD KC_LGUI | ||
| 157 | #define KC_LWIN KC_LGUI | ||
| 158 | #define KC_RCTL KC_RCTRL | ||
| 159 | #define KC_RSFT KC_RSHIFT | ||
| 160 | #define KC_ALGR KC_RALT | ||
| 161 | #define KC_ROPT KC_RALT | ||
| 162 | #define KC_RCMD KC_RGUI | ||
| 163 | #define KC_RWIN KC_RGUI | ||
| 164 | |||
| 165 | /* Generic Desktop Page (0x01) */ | ||
| 166 | #define KC_PWR KC_SYSTEM_POWER | ||
| 167 | #define KC_SLEP KC_SYSTEM_SLEEP | ||
| 168 | #define KC_WAKE KC_SYSTEM_WAKE | ||
| 169 | |||
| 170 | /* Consumer Page (0x0C) */ | ||
| 171 | #define KC_MUTE KC_AUDIO_MUTE | ||
| 172 | #define KC_VOLU KC_AUDIO_VOL_UP | ||
| 173 | #define KC_VOLD KC_AUDIO_VOL_DOWN | ||
| 174 | #define KC_MNXT KC_MEDIA_NEXT_TRACK | ||
| 175 | #define KC_MPRV KC_MEDIA_PREV_TRACK | ||
| 176 | #define KC_MSTP KC_MEDIA_STOP | ||
| 177 | #define KC_MPLY KC_MEDIA_PLAY_PAUSE | ||
| 178 | #define KC_MSEL KC_MEDIA_SELECT | ||
| 179 | #define KC_EJCT KC_MEDIA_EJECT | ||
| 180 | #define KC_CALC KC_CALCULATOR | ||
| 181 | #define KC_MYCM KC_MY_COMPUTER | ||
| 182 | #define KC_WSCH KC_WWW_SEARCH | ||
| 183 | #define KC_WHOM KC_WWW_HOME | ||
| 184 | #define KC_WBAK KC_WWW_BACK | ||
| 185 | #define KC_WFWD KC_WWW_FORWARD | ||
| 186 | #define KC_WSTP KC_WWW_STOP | ||
| 187 | #define KC_WREF KC_WWW_REFRESH | ||
| 188 | #define KC_WFAV KC_WWW_FAVORITES | ||
| 189 | #define KC_MFFD KC_MEDIA_FAST_FORWARD | ||
| 190 | #define KC_MRWD KC_MEDIA_REWIND | ||
| 191 | #define KC_BRIU KC_BRIGHTNESS_UP | ||
| 192 | #define KC_BRID KC_BRIGHTNESS_DOWN | ||
| 193 | |||
| 194 | /* System Specific */ | ||
| 195 | #define KC_BRMU KC_PAUSE | ||
| 196 | #define KC_BRMD KC_SCROLLLOCK | ||
| 197 | |||
| 198 | /* Mouse Keys */ | ||
| 199 | #define KC_MS_U KC_MS_UP | ||
| 200 | #define KC_MS_D KC_MS_DOWN | ||
| 201 | #define KC_MS_L KC_MS_LEFT | ||
| 202 | #define KC_MS_R KC_MS_RIGHT | ||
| 203 | #define KC_BTN1 KC_MS_BTN1 | ||
| 204 | #define KC_BTN2 KC_MS_BTN2 | ||
| 205 | #define KC_BTN3 KC_MS_BTN3 | ||
| 206 | #define KC_BTN4 KC_MS_BTN4 | ||
| 207 | #define KC_BTN5 KC_MS_BTN5 | ||
| 208 | #define KC_BTN6 KC_MS_BTN6 | ||
| 209 | #define KC_BTN7 KC_MS_BTN7 | ||
| 210 | #define KC_BTN8 KC_MS_BTN8 | ||
| 211 | #define KC_WH_U KC_MS_WH_UP | ||
| 212 | #define KC_WH_D KC_MS_WH_DOWN | ||
| 213 | #define KC_WH_L KC_MS_WH_LEFT | ||
| 214 | #define KC_WH_R KC_MS_WH_RIGHT | ||
| 215 | #define KC_ACL0 KC_MS_ACCEL0 | ||
| 216 | #define KC_ACL1 KC_MS_ACCEL1 | ||
| 217 | #define KC_ACL2 KC_MS_ACCEL2 | ||
| 218 | |||
| 219 | /* Keyboard/Keypad Page (0x07) */ | ||
| 220 | enum hid_keyboard_keypad_usage { | ||
| 221 | KC_NO = 0x00, | ||
| 222 | KC_ROLL_OVER, | ||
| 223 | KC_POST_FAIL, | ||
| 224 | KC_UNDEFINED, | ||
| 225 | KC_A, | ||
| 226 | KC_B, | ||
| 227 | KC_C, | ||
| 228 | KC_D, | ||
| 229 | KC_E, | ||
| 230 | KC_F, | ||
| 231 | KC_G, | ||
| 232 | KC_H, | ||
| 233 | KC_I, | ||
| 234 | KC_J, | ||
| 235 | KC_K, | ||
| 236 | KC_L, | ||
| 237 | KC_M, // 0x10 | ||
| 238 | KC_N, | ||
| 239 | KC_O, | ||
| 240 | KC_P, | ||
| 241 | KC_Q, | ||
| 242 | KC_R, | ||
| 243 | KC_S, | ||
| 244 | KC_T, | ||
| 245 | KC_U, | ||
| 246 | KC_V, | ||
| 247 | KC_W, | ||
| 248 | KC_X, | ||
| 249 | KC_Y, | ||
| 250 | KC_Z, | ||
| 251 | KC_1, | ||
| 252 | KC_2, | ||
| 253 | KC_3, // 0x20 | ||
| 254 | KC_4, | ||
| 255 | KC_5, | ||
| 256 | KC_6, | ||
| 257 | KC_7, | ||
| 258 | KC_8, | ||
| 259 | KC_9, | ||
| 260 | KC_0, | ||
| 261 | KC_ENTER, | ||
| 262 | KC_ESCAPE, | ||
| 263 | KC_BSPACE, | ||
| 264 | KC_TAB, | ||
| 265 | KC_SPACE, | ||
| 266 | KC_MINUS, | ||
| 267 | KC_EQUAL, | ||
| 268 | KC_LBRACKET, | ||
| 269 | KC_RBRACKET, // 0x30 | ||
| 270 | KC_BSLASH, | ||
| 271 | KC_NONUS_HASH, | ||
| 272 | KC_SCOLON, | ||
| 273 | KC_QUOTE, | ||
| 274 | KC_GRAVE, | ||
| 275 | KC_COMMA, | ||
| 276 | KC_DOT, | ||
| 277 | KC_SLASH, | ||
| 278 | KC_CAPSLOCK, | ||
| 279 | KC_F1, | ||
| 280 | KC_F2, | ||
| 281 | KC_F3, | ||
| 282 | KC_F4, | ||
| 283 | KC_F5, | ||
| 284 | KC_F6, | ||
| 285 | KC_F7, // 0x40 | ||
| 286 | KC_F8, | ||
| 287 | KC_F9, | ||
| 288 | KC_F10, | ||
| 289 | KC_F11, | ||
| 290 | KC_F12, | ||
| 291 | KC_PSCREEN, | ||
| 292 | KC_SCROLLLOCK, | ||
| 293 | KC_PAUSE, | ||
| 294 | KC_INSERT, | ||
| 295 | KC_HOME, | ||
| 296 | KC_PGUP, | ||
| 297 | KC_DELETE, | ||
| 298 | KC_END, | ||
| 299 | KC_PGDOWN, | ||
| 300 | KC_RIGHT, | ||
| 301 | KC_LEFT, // 0x50 | ||
| 302 | KC_DOWN, | ||
| 303 | KC_UP, | ||
| 304 | KC_NUMLOCK, | ||
| 305 | KC_KP_SLASH, | ||
| 306 | KC_KP_ASTERISK, | ||
| 307 | KC_KP_MINUS, | ||
| 308 | KC_KP_PLUS, | ||
| 309 | KC_KP_ENTER, | ||
| 310 | KC_KP_1, | ||
| 311 | KC_KP_2, | ||
| 312 | KC_KP_3, | ||
| 313 | KC_KP_4, | ||
| 314 | KC_KP_5, | ||
| 315 | KC_KP_6, | ||
| 316 | KC_KP_7, | ||
| 317 | KC_KP_8, // 0x60 | ||
| 318 | KC_KP_9, | ||
| 319 | KC_KP_0, | ||
| 320 | KC_KP_DOT, | ||
| 321 | KC_NONUS_BSLASH, | ||
| 322 | KC_APPLICATION, | ||
| 323 | KC_POWER, | ||
| 324 | KC_KP_EQUAL, | ||
| 325 | KC_F13, | ||
| 326 | KC_F14, | ||
| 327 | KC_F15, | ||
| 328 | KC_F16, | ||
| 329 | KC_F17, | ||
| 330 | KC_F18, | ||
| 331 | KC_F19, | ||
| 332 | KC_F20, | ||
| 333 | KC_F21, // 0x70 | ||
| 334 | KC_F22, | ||
| 335 | KC_F23, | ||
| 336 | KC_F24, | ||
| 337 | KC_EXECUTE, | ||
| 338 | KC_HELP, | ||
| 339 | KC_MENU, | ||
| 340 | KC_SELECT, | ||
| 341 | KC_STOP, | ||
| 342 | KC_AGAIN, | ||
| 343 | KC_UNDO, | ||
| 344 | KC_CUT, | ||
| 345 | KC_COPY, | ||
| 346 | KC_PASTE, | ||
| 347 | KC_FIND, | ||
| 348 | KC__MUTE, | ||
| 349 | KC__VOLUP, // 0x80 | ||
| 350 | KC__VOLDOWN, | ||
| 351 | KC_LOCKING_CAPS, | ||
| 352 | KC_LOCKING_NUM, | ||
| 353 | KC_LOCKING_SCROLL, | ||
| 354 | KC_KP_COMMA, | ||
| 355 | KC_KP_EQUAL_AS400, | ||
| 356 | KC_INT1, | ||
| 357 | KC_INT2, | ||
| 358 | KC_INT3, | ||
| 359 | KC_INT4, | ||
| 360 | KC_INT5, | ||
| 361 | KC_INT6, | ||
| 362 | KC_INT7, | ||
| 363 | KC_INT8, | ||
| 364 | KC_INT9, | ||
| 365 | KC_LANG1, // 0x90 | ||
| 366 | KC_LANG2, | ||
| 367 | KC_LANG3, | ||
| 368 | KC_LANG4, | ||
| 369 | KC_LANG5, | ||
| 370 | KC_LANG6, | ||
| 371 | KC_LANG7, | ||
| 372 | KC_LANG8, | ||
| 373 | KC_LANG9, | ||
| 374 | KC_ALT_ERASE, | ||
| 375 | KC_SYSREQ, | ||
| 376 | KC_CANCEL, | ||
| 377 | KC_CLEAR, | ||
| 378 | KC_PRIOR, | ||
| 379 | KC_RETURN, | ||
| 380 | KC_SEPARATOR, | ||
| 381 | KC_OUT, // 0xA0 | ||
| 382 | KC_OPER, | ||
| 383 | KC_CLEAR_AGAIN, | ||
| 384 | KC_CRSEL, | ||
| 385 | KC_EXSEL, | ||
| 386 | |||
| 387 | #if 0 | ||
| 388 | // *************************************************************** | ||
| 389 | // These keycodes are present in the HID spec, but are * | ||
| 390 | // nonfunctional on modern OSes. QMK uses this range (0xA5-0xDF) * | ||
| 391 | // for the media and function keys instead - see below. * | ||
| 392 | // *************************************************************** | ||
| 393 | |||
| 394 | KC_KP_00 = 0xB0, | ||
| 395 | KC_KP_000, | ||
| 396 | KC_THOUSANDS_SEPARATOR, | ||
| 397 | KC_DECIMAL_SEPARATOR, | ||
| 398 | KC_CURRENCY_UNIT, | ||
| 399 | KC_CURRENCY_SUB_UNIT, | ||
| 400 | KC_KP_LPAREN, | ||
| 401 | KC_KP_RPAREN, | ||
| 402 | KC_KP_LCBRACKET, | ||
| 403 | KC_KP_RCBRACKET, | ||
| 404 | KC_KP_TAB, | ||
| 405 | KC_KP_BSPACE, | ||
| 406 | KC_KP_A, | ||
| 407 | KC_KP_B, | ||
| 408 | KC_KP_C, | ||
| 409 | KC_KP_D, | ||
| 410 | KC_KP_E, //0xC0 | ||
| 411 | KC_KP_F, | ||
| 412 | KC_KP_XOR, | ||
| 413 | KC_KP_HAT, | ||
| 414 | KC_KP_PERC, | ||
| 415 | KC_KP_LT, | ||
| 416 | KC_KP_GT, | ||
| 417 | KC_KP_AND, | ||
| 418 | KC_KP_LAZYAND, | ||
| 419 | KC_KP_OR, | ||
| 420 | KC_KP_LAZYOR, | ||
| 421 | KC_KP_COLON, | ||
| 422 | KC_KP_HASH, | ||
| 423 | KC_KP_SPACE, | ||
| 424 | KC_KP_ATMARK, | ||
| 425 | KC_KP_EXCLAMATION, | ||
| 426 | KC_KP_MEM_STORE, //0xD0 | ||
| 427 | KC_KP_MEM_RECALL, | ||
| 428 | KC_KP_MEM_CLEAR, | ||
| 429 | KC_KP_MEM_ADD, | ||
| 430 | KC_KP_MEM_SUB, | ||
| 431 | KC_KP_MEM_MUL, | ||
| 432 | KC_KP_MEM_DIV, | ||
| 433 | KC_KP_PLUS_MINUS, | ||
| 434 | KC_KP_CLEAR, | ||
| 435 | KC_KP_CLEAR_ENTRY, | ||
| 436 | KC_KP_BINARY, | ||
| 437 | KC_KP_OCTAL, | ||
| 438 | KC_KP_DECIMAL, | ||
| 439 | KC_KP_HEXADECIMAL, | ||
| 440 | #endif | ||
| 441 | |||
| 442 | /* Modifiers */ | ||
| 443 | KC_LCTRL = 0xE0, | ||
| 444 | KC_LSHIFT, | ||
| 445 | KC_LALT, | ||
| 446 | KC_LGUI, | ||
| 447 | KC_RCTRL, | ||
| 448 | KC_RSHIFT, | ||
| 449 | KC_RALT, | ||
| 450 | KC_RGUI | ||
| 451 | |||
| 452 | // ********************************************** | ||
| 453 | // * 0xF0-0xFF are unallocated in the HID spec. * | ||
| 454 | // * QMK uses these for Mouse Keys - see below. * | ||
| 455 | // ********************************************** | ||
| 456 | }; | ||
| 457 | |||
| 458 | /* Media and Function keys */ | ||
| 459 | enum internal_special_keycodes { | ||
| 460 | /* Generic Desktop Page (0x01) */ | ||
| 461 | KC_SYSTEM_POWER = 0xA5, | ||
| 462 | KC_SYSTEM_SLEEP, | ||
| 463 | KC_SYSTEM_WAKE, | ||
| 464 | |||
| 465 | /* Consumer Page (0x0C) */ | ||
| 466 | KC_AUDIO_MUTE, | ||
| 467 | KC_AUDIO_VOL_UP, | ||
| 468 | KC_AUDIO_VOL_DOWN, | ||
| 469 | KC_MEDIA_NEXT_TRACK, | ||
| 470 | KC_MEDIA_PREV_TRACK, | ||
| 471 | KC_MEDIA_STOP, | ||
| 472 | KC_MEDIA_PLAY_PAUSE, | ||
| 473 | KC_MEDIA_SELECT, | ||
| 474 | KC_MEDIA_EJECT, // 0xB0 | ||
| 475 | KC_MAIL, | ||
| 476 | KC_CALCULATOR, | ||
| 477 | KC_MY_COMPUTER, | ||
| 478 | KC_WWW_SEARCH, | ||
| 479 | KC_WWW_HOME, | ||
| 480 | KC_WWW_BACK, | ||
| 481 | KC_WWW_FORWARD, | ||
| 482 | KC_WWW_STOP, | ||
| 483 | KC_WWW_REFRESH, | ||
| 484 | KC_WWW_FAVORITES, | ||
| 485 | KC_MEDIA_FAST_FORWARD, | ||
| 486 | KC_MEDIA_REWIND, | ||
| 487 | KC_BRIGHTNESS_UP, | ||
| 488 | KC_BRIGHTNESS_DOWN, | ||
| 489 | |||
| 490 | /* Fn keys */ | ||
| 491 | KC_FN0 = 0xC0, | ||
| 492 | KC_FN1, | ||
| 493 | KC_FN2, | ||
| 494 | KC_FN3, | ||
| 495 | KC_FN4, | ||
| 496 | KC_FN5, | ||
| 497 | KC_FN6, | ||
| 498 | KC_FN7, | ||
| 499 | KC_FN8, | ||
| 500 | KC_FN9, | ||
| 501 | KC_FN10, | ||
| 502 | KC_FN11, | ||
| 503 | KC_FN12, | ||
| 504 | KC_FN13, | ||
| 505 | KC_FN14, | ||
| 506 | KC_FN15, | ||
| 507 | KC_FN16, // 0xD0 | ||
| 508 | KC_FN17, | ||
| 509 | KC_FN18, | ||
| 510 | KC_FN19, | ||
| 511 | KC_FN20, | ||
| 512 | KC_FN21, | ||
| 513 | KC_FN22, | ||
| 514 | KC_FN23, | ||
| 515 | KC_FN24, | ||
| 516 | KC_FN25, | ||
| 517 | KC_FN26, | ||
| 518 | KC_FN27, | ||
| 519 | KC_FN28, | ||
| 520 | KC_FN29, | ||
| 521 | KC_FN30, | ||
| 522 | KC_FN31 | ||
| 523 | }; | ||
| 524 | |||
| 525 | enum mouse_keys { | ||
| 526 | /* Mouse Buttons */ | ||
| 527 | #ifdef VIA_ENABLE | ||
| 528 | KC_MS_UP = 0xF0, | ||
| 529 | #else | ||
| 530 | KC_MS_UP = 0xED, | ||
| 531 | #endif | ||
| 532 | KC_MS_DOWN, | ||
| 533 | KC_MS_LEFT, | ||
| 534 | KC_MS_RIGHT, // 0xF0 | ||
| 535 | KC_MS_BTN1, | ||
| 536 | KC_MS_BTN2, | ||
| 537 | KC_MS_BTN3, | ||
| 538 | KC_MS_BTN4, | ||
| 539 | KC_MS_BTN5, | ||
| 540 | #ifdef VIA_ENABLE | ||
| 541 | KC_MS_BTN6 = KC_MS_BTN5, | ||
| 542 | KC_MS_BTN7 = KC_MS_BTN5, | ||
| 543 | KC_MS_BTN8 = KC_MS_BTN5, | ||
| 544 | #else | ||
| 545 | KC_MS_BTN6, | ||
| 546 | KC_MS_BTN7, | ||
| 547 | KC_MS_BTN8, | ||
| 548 | #endif | ||
| 549 | |||
| 550 | /* Mouse Wheel */ | ||
| 551 | KC_MS_WH_UP, | ||
| 552 | KC_MS_WH_DOWN, | ||
| 553 | KC_MS_WH_LEFT, | ||
| 554 | KC_MS_WH_RIGHT, | ||
| 555 | |||
| 556 | /* Acceleration */ | ||
| 557 | KC_MS_ACCEL0, | ||
| 558 | KC_MS_ACCEL1, | ||
| 559 | KC_MS_ACCEL2 // 0xFF | ||
| 560 | }; | ||
diff --git a/tmk_core/common/lib_printf.mk b/tmk_core/common/lib_printf.mk deleted file mode 100644 index 10d2d8468..000000000 --- a/tmk_core/common/lib_printf.mk +++ /dev/null | |||
| @@ -1,9 +0,0 @@ | |||
| 1 | PRINTF_PATH = $(LIB_PATH)/printf | ||
| 2 | |||
| 3 | TMK_COMMON_SRC += $(PRINTF_PATH)/printf.c | ||
| 4 | TMK_COMMON_SRC += $(COMMON_DIR)/printf.c | ||
| 5 | TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_FLOAT | ||
| 6 | TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_EXPONENTIAL | ||
| 7 | TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_LONG_LONG | ||
| 8 | TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_PTRDIFF_T | ||
| 9 | VPATH += $(PRINTF_PATH) | ||
diff --git a/tmk_core/common/nodebug.h b/tmk_core/common/nodebug.h deleted file mode 100644 index 0b176684b..000000000 --- a/tmk_core/common/nodebug.h +++ /dev/null | |||
| @@ -1,26 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2013 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #ifndef NO_DEBUG | ||
| 21 | # define NO_DEBUG | ||
| 22 | # include "debug.h" | ||
| 23 | # undef NO_DEBUG | ||
| 24 | #else | ||
| 25 | # include "debug.h" | ||
| 26 | #endif | ||
diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h deleted file mode 100644 index 8c055f549..000000000 --- a/tmk_core/common/print.h +++ /dev/null | |||
| @@ -1,135 +0,0 @@ | |||
| 1 | /* Copyright 2012 Jun Wako <wakojun@gmail.com> */ | ||
| 2 | /* Very basic print functions, intended to be used with usb_debug_only.c | ||
| 3 | * http://www.pjrc.com/teensy/ | ||
| 4 | * Copyright (c) 2008 PJRC.COM, LLC | ||
| 5 | * | ||
| 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 7 | * of this software and associated documentation files (the "Software"), to deal | ||
| 8 | * in the Software without restriction, including without limitation the rights | ||
| 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 10 | * copies of the Software, and to permit persons to whom the Software is | ||
| 11 | * furnished to do so, subject to the following conditions: | ||
| 12 | * | ||
| 13 | * The above copyright notice and this permission notice shall be included in | ||
| 14 | * all copies or substantial portions of the Software. | ||
| 15 | * | ||
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 22 | * THE SOFTWARE. | ||
| 23 | */ | ||
| 24 | |||
| 25 | #pragma once | ||
| 26 | |||
| 27 | #include <stdint.h> | ||
| 28 | #include <stdbool.h> | ||
| 29 | #include "util.h" | ||
| 30 | #include "sendchar.h" | ||
| 31 | #include "progmem.h" | ||
| 32 | |||
| 33 | void print_set_sendchar(sendchar_func_t func); | ||
| 34 | |||
| 35 | #ifndef NO_PRINT | ||
| 36 | # if __has_include_next("_print.h") | ||
| 37 | # include_next "_print.h" /* Include the platforms print.h */ | ||
| 38 | # else | ||
| 39 | // Fall back to lib/printf | ||
| 40 | # include "printf.h" // lib/printf/printf.h | ||
| 41 | |||
| 42 | // Create user & normal print defines | ||
| 43 | # define print(s) printf(s) | ||
| 44 | # define println(s) printf(s "\r\n") | ||
| 45 | # define xprintf printf | ||
| 46 | # define uprint(s) printf(s) | ||
| 47 | # define uprintln(s) printf(s "\r\n") | ||
| 48 | # define uprintf printf | ||
| 49 | |||
| 50 | # endif /* __has_include_next("_print.h") */ | ||
| 51 | #else /* NO_PRINT */ | ||
| 52 | # undef xprintf | ||
| 53 | // Remove print defines | ||
| 54 | # define print(s) | ||
| 55 | # define println(s) | ||
| 56 | # define xprintf(fmt, ...) | ||
| 57 | # define uprintf(fmt, ...) | ||
| 58 | # define uprint(s) | ||
| 59 | # define uprintln(s) | ||
| 60 | |||
| 61 | #endif /* NO_PRINT */ | ||
| 62 | |||
| 63 | #ifdef USER_PRINT | ||
| 64 | // Remove normal print defines | ||
| 65 | # undef print | ||
| 66 | # undef println | ||
| 67 | # undef xprintf | ||
| 68 | # define print(s) | ||
| 69 | # define println(s) | ||
| 70 | # define xprintf(fmt, ...) | ||
| 71 | #endif | ||
| 72 | |||
| 73 | #define print_dec(i) xprintf("%u", i) | ||
| 74 | #define print_decs(i) xprintf("%d", i) | ||
| 75 | /* hex */ | ||
| 76 | #define print_hex4(i) xprintf("%X", i) | ||
| 77 | #define print_hex8(i) xprintf("%02X", i) | ||
| 78 | #define print_hex16(i) xprintf("%04X", i) | ||
| 79 | #define print_hex32(i) xprintf("%08lX", i) | ||
| 80 | /* binary */ | ||
| 81 | #define print_bin4(i) xprintf("%04b", i) | ||
| 82 | #define print_bin8(i) xprintf("%08b", i) | ||
| 83 | #define print_bin16(i) xprintf("%016b", i) | ||
| 84 | #define print_bin32(i) xprintf("%032lb", i) | ||
| 85 | #define print_bin_reverse8(i) xprintf("%08b", bitrev(i)) | ||
| 86 | #define print_bin_reverse16(i) xprintf("%016b", bitrev16(i)) | ||
| 87 | #define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i)) | ||
| 88 | /* print value utility */ | ||
| 89 | #define print_val_dec(v) xprintf(#v ": %u\n", v) | ||
| 90 | #define print_val_decs(v) xprintf(#v ": %d\n", v) | ||
| 91 | #define print_val_hex8(v) xprintf(#v ": %X\n", v) | ||
| 92 | #define print_val_hex16(v) xprintf(#v ": %02X\n", v) | ||
| 93 | #define print_val_hex32(v) xprintf(#v ": %04lX\n", v) | ||
| 94 | #define print_val_bin8(v) xprintf(#v ": %08b\n", v) | ||
| 95 | #define print_val_bin16(v) xprintf(#v ": %016b\n", v) | ||
| 96 | #define print_val_bin32(v) xprintf(#v ": %032lb\n", v) | ||
| 97 | #define print_val_bin_reverse8(v) xprintf(#v ": %08b\n", bitrev(v)) | ||
| 98 | #define print_val_bin_reverse16(v) xprintf(#v ": %016b\n", bitrev16(v)) | ||
| 99 | #define print_val_bin_reverse32(v) xprintf(#v ": %032lb\n", bitrev32(v)) | ||
| 100 | |||
| 101 | // User print disables the normal print messages in the body of QMK/TMK code and | ||
| 102 | // is meant as a lightweight alternative to NOPRINT. Use it when you only want to do | ||
| 103 | // a spot of debugging but lack flash resources for allowing all of the codebase to | ||
| 104 | // print (and store their wasteful strings). | ||
| 105 | // | ||
| 106 | // !!! DO NOT USE USER PRINT CALLS IN THE BODY OF QMK/TMK !!! | ||
| 107 | |||
| 108 | /* decimal */ | ||
| 109 | #define uprint_dec(i) uprintf("%u", i) | ||
| 110 | #define uprint_decs(i) uprintf("%d", i) | ||
| 111 | /* hex */ | ||
| 112 | #define uprint_hex4(i) uprintf("%X", i) | ||
| 113 | #define uprint_hex8(i) uprintf("%02X", i) | ||
| 114 | #define uprint_hex16(i) uprintf("%04X", i) | ||
| 115 | #define uprint_hex32(i) uprintf("%08lX", i) | ||
| 116 | /* binary */ | ||
| 117 | #define uprint_bin4(i) uprintf("%04b", i) | ||
| 118 | #define uprint_bin8(i) uprintf("%08b", i) | ||
| 119 | #define uprint_bin16(i) uprintf("%016b", i) | ||
| 120 | #define uprint_bin32(i) uprintf("%032lb", i) | ||
| 121 | #define uprint_bin_reverse8(i) uprintf("%08b", bitrev(i)) | ||
| 122 | #define uprint_bin_reverse16(i) uprintf("%016b", bitrev16(i)) | ||
| 123 | #define uprint_bin_reverse32(i) uprintf("%032lb", bitrev32(i)) | ||
| 124 | /* print value utility */ | ||
| 125 | #define uprint_val_dec(v) uprintf(#v ": %u\n", v) | ||
| 126 | #define uprint_val_decs(v) uprintf(#v ": %d\n", v) | ||
| 127 | #define uprint_val_hex8(v) uprintf(#v ": %X\n", v) | ||
| 128 | #define uprint_val_hex16(v) uprintf(#v ": %02X\n", v) | ||
| 129 | #define uprint_val_hex32(v) uprintf(#v ": %04lX\n", v) | ||
| 130 | #define uprint_val_bin8(v) uprintf(#v ": %08b\n", v) | ||
| 131 | #define uprint_val_bin16(v) uprintf(#v ": %016b\n", v) | ||
| 132 | #define uprint_val_bin32(v) uprintf(#v ": %032lb\n", v) | ||
| 133 | #define uprint_val_bin_reverse8(v) uprintf(#v ": %08b\n", bitrev(v)) | ||
| 134 | #define uprint_val_bin_reverse16(v) uprintf(#v ": %016b\n", bitrev16(v)) | ||
| 135 | #define uprint_val_bin_reverse32(v) uprintf(#v ": %032lb\n", bitrev32(v)) | ||
diff --git a/tmk_core/common/printf.c b/tmk_core/common/printf.c deleted file mode 100644 index e8440e55e..000000000 --- a/tmk_core/common/printf.c +++ /dev/null | |||
| @@ -1,27 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | #include <stddef.h> | ||
| 18 | #include "sendchar.h" | ||
| 19 | |||
| 20 | // bind lib/printf to console interface - sendchar | ||
| 21 | |||
| 22 | static int8_t null_sendchar_func(uint8_t c) { return 0; } | ||
| 23 | static sendchar_func_t func = null_sendchar_func; | ||
| 24 | |||
| 25 | void print_set_sendchar(sendchar_func_t send) { func = send; } | ||
| 26 | |||
| 27 | void _putchar(char character) { func(character); } | ||
diff --git a/tmk_core/common/progmem.h b/tmk_core/common/progmem.h index 4e4771e52..a70d8e299 100644 --- a/tmk_core/common/progmem.h +++ b/tmk_core/common/progmem.h | |||
| @@ -3,7 +3,9 @@ | |||
| 3 | #if defined(__AVR__) | 3 | #if defined(__AVR__) |
| 4 | # include <avr/pgmspace.h> | 4 | # include <avr/pgmspace.h> |
| 5 | #else | 5 | #else |
| 6 | # include <string.h> | ||
| 6 | # define PROGMEM | 7 | # define PROGMEM |
| 8 | # define __flash | ||
| 7 | # define PSTR(x) x | 9 | # define PSTR(x) x |
| 8 | # define PGM_P const char* | 10 | # define PGM_P const char* |
| 9 | # define memcpy_P(dest, src, n) memcpy(dest, src, n) | 11 | # define memcpy_P(dest, src, n) memcpy(dest, src, n) |
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h index db6370657..f2223e806 100644 --- a/tmk_core/common/report.h +++ b/tmk_core/common/report.h | |||
| @@ -30,7 +30,8 @@ enum hid_report_ids { | |||
| 30 | REPORT_ID_SYSTEM, | 30 | REPORT_ID_SYSTEM, |
| 31 | REPORT_ID_CONSUMER, | 31 | REPORT_ID_CONSUMER, |
| 32 | REPORT_ID_NKRO, | 32 | REPORT_ID_NKRO, |
| 33 | REPORT_ID_JOYSTICK | 33 | REPORT_ID_JOYSTICK, |
| 34 | REPORT_ID_DIGITIZER | ||
| 34 | }; | 35 | }; |
| 35 | 36 | ||
| 36 | /* Mouse buttons */ | 37 | /* Mouse buttons */ |
| @@ -206,6 +207,17 @@ typedef struct { | |||
| 206 | } __attribute__((packed)) report_mouse_t; | 207 | } __attribute__((packed)) report_mouse_t; |
| 207 | 208 | ||
| 208 | typedef struct { | 209 | typedef struct { |
| 210 | #ifdef DIGITIZER_SHARED_EP | ||
| 211 | uint8_t report_id; | ||
| 212 | #endif | ||
| 213 | uint8_t tip : 1; | ||
| 214 | uint8_t inrange : 1; | ||
| 215 | uint8_t pad2 : 6; | ||
| 216 | uint16_t x; | ||
| 217 | uint16_t y; | ||
| 218 | } __attribute__((packed)) report_digitizer_t; | ||
| 219 | |||
| 220 | typedef struct { | ||
| 209 | #if JOYSTICK_AXES_COUNT > 0 | 221 | #if JOYSTICK_AXES_COUNT > 0 |
| 210 | # if JOYSTICK_AXES_RESOLUTION > 8 | 222 | # if JOYSTICK_AXES_RESOLUTION > 8 |
| 211 | int16_t axes[JOYSTICK_AXES_COUNT]; | 223 | int16_t axes[JOYSTICK_AXES_COUNT]; |
diff --git a/tmk_core/common/sendchar.h b/tmk_core/common/sendchar.h deleted file mode 100644 index edcddaa6b..000000000 --- a/tmk_core/common/sendchar.h +++ /dev/null | |||
| @@ -1,33 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <stdint.h> | ||
| 21 | |||
| 22 | #ifdef __cplusplus | ||
| 23 | extern "C" { | ||
| 24 | #endif | ||
| 25 | |||
| 26 | typedef int8_t (*sendchar_func_t)(uint8_t c); | ||
| 27 | |||
| 28 | /* transmit a character. return 0 on success, -1 on error. */ | ||
| 29 | int8_t sendchar(uint8_t c); | ||
| 30 | |||
| 31 | #ifdef __cplusplus | ||
| 32 | } | ||
| 33 | #endif | ||
diff --git a/tmk_core/common/sendchar_null.c b/tmk_core/common/sendchar_null.c deleted file mode 100644 index fb67f7086..000000000 --- a/tmk_core/common/sendchar_null.c +++ /dev/null | |||
| @@ -1,19 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | #include "sendchar.h" | ||
| 18 | |||
| 19 | __attribute__((weak)) int8_t sendchar(uint8_t c) { return 0; } | ||
diff --git a/tmk_core/common/sendchar_uart.c b/tmk_core/common/sendchar_uart.c deleted file mode 100644 index 2fc48baff..000000000 --- a/tmk_core/common/sendchar_uart.c +++ /dev/null | |||
| @@ -1,23 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 16 | */ | ||
| 17 | #include "uart.h" | ||
| 18 | #include "sendchar.h" | ||
| 19 | |||
| 20 | int8_t sendchar(uint8_t c) { | ||
| 21 | uart_putchar(c); | ||
| 22 | return 0; | ||
| 23 | } | ||
diff --git a/tmk_core/common/sync_timer.c b/tmk_core/common/sync_timer.c index de24b463b..68b92d8b4 100644 --- a/tmk_core/common/sync_timer.c +++ b/tmk_core/common/sync_timer.c | |||
| @@ -26,7 +26,7 @@ SOFTWARE. | |||
| 26 | #include "sync_timer.h" | 26 | #include "sync_timer.h" |
| 27 | #include "keyboard.h" | 27 | #include "keyboard.h" |
| 28 | 28 | ||
| 29 | #if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) | 29 | #if (defined(SPLIT_KEYBOARD) || defined(SERIAL_LINK_ENABLE)) && !defined(DISABLE_SYNC_TIMER) |
| 30 | volatile int32_t sync_timer_ms; | 30 | volatile int32_t sync_timer_ms; |
| 31 | 31 | ||
| 32 | void sync_timer_init(void) { sync_timer_ms = 0; } | 32 | void sync_timer_init(void) { sync_timer_ms = 0; } |
diff --git a/tmk_core/common/sync_timer.h b/tmk_core/common/sync_timer.h index 9ddef45bb..744e2b50d 100644 --- a/tmk_core/common/sync_timer.h +++ b/tmk_core/common/sync_timer.h | |||
| @@ -32,7 +32,7 @@ SOFTWARE. | |||
| 32 | extern "C" { | 32 | extern "C" { |
| 33 | #endif | 33 | #endif |
| 34 | 34 | ||
| 35 | #if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) | 35 | #if (defined(SPLIT_KEYBOARD) || defined(SERIAL_LINK_ENABLE)) && !defined(DISABLE_SYNC_TIMER) |
| 36 | void sync_timer_init(void); | 36 | void sync_timer_init(void); |
| 37 | void sync_timer_update(uint32_t time); | 37 | void sync_timer_update(uint32_t time); |
| 38 | uint16_t sync_timer_read(void); | 38 | uint16_t sync_timer_read(void); |
diff --git a/tmk_core/common/test/platform.c b/tmk_core/common/test/platform.c new file mode 100644 index 000000000..8ddceeda8 --- /dev/null +++ b/tmk_core/common/test/platform.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* Copyright 2021 QMK | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 3 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "platform_deps.h" | ||
| 18 | |||
| 19 | void platform_setup(void) { | ||
| 20 | // do nothing | ||
| 21 | } \ No newline at end of file | ||
diff --git a/tmk_core/common/timer.h b/tmk_core/common/timer.h index abddcea85..02e39e79e 100644 --- a/tmk_core/common/timer.h +++ b/tmk_core/common/timer.h | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> |
| 3 | Copyright 2021 Simon Arlott | ||
| 3 | 4 | ||
| 4 | This program is free software: you can redistribute it and/or modify | 5 | This program is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
| @@ -17,6 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 17 | 18 | ||
| 18 | #pragma once | 19 | #pragma once |
| 19 | 20 | ||
| 21 | #if __has_include_next("_timer.h") | ||
| 22 | # include_next "_timer.h" /* Include the platform's _timer.h */ | ||
| 23 | #endif | ||
| 24 | |||
| 20 | #include <stdint.h> | 25 | #include <stdint.h> |
| 21 | 26 | ||
| 22 | #define TIMER_DIFF(a, b, max) ((max == UINT8_MAX) ? ((uint8_t)((a) - (b))) : ((max == UINT16_MAX) ? ((uint16_t)((a) - (b))) : ((max == UINT32_MAX) ? ((uint32_t)((a) - (b))) : ((a) >= (b) ? (a) - (b) : (max) + 1 - (b) + (a))))) | 27 | #define TIMER_DIFF(a, b, max) ((max == UINT8_MAX) ? ((uint8_t)((a) - (b))) : ((max == UINT16_MAX) ? ((uint16_t)((a) - (b))) : ((max == UINT32_MAX) ? ((uint32_t)((a) - (b))) : ((a) >= (b) ? (a) - (b) : (max) + 1 - (b) + (a))))) |
| @@ -42,6 +47,21 @@ uint32_t timer_elapsed32(uint32_t last); | |||
| 42 | #define timer_expired(current, future) ((uint16_t)(current - future) < UINT16_MAX / 2) | 47 | #define timer_expired(current, future) ((uint16_t)(current - future) < UINT16_MAX / 2) |
| 43 | #define timer_expired32(current, future) ((uint32_t)(current - future) < UINT32_MAX / 2) | 48 | #define timer_expired32(current, future) ((uint32_t)(current - future) < UINT32_MAX / 2) |
| 44 | 49 | ||
| 50 | // Use an appropriate timer integer size based on architecture (16-bit will overflow sooner) | ||
| 51 | #if FAST_TIMER_T_SIZE < 32 | ||
| 52 | # define TIMER_DIFF_FAST(a, b) TIMER_DIFF_16(a, b) | ||
| 53 | # define timer_expired_fast(current, future) timer_expired(current, future) | ||
| 54 | typedef uint16_t fast_timer_t; | ||
| 55 | fast_timer_t inline timer_read_fast(void) { return timer_read(); } | ||
| 56 | fast_timer_t inline timer_elapsed_fast(fast_timer_t last) { return timer_elapsed(last); } | ||
| 57 | #else | ||
| 58 | # define TIMER_DIFF_FAST(a, b) TIMER_DIFF_32(a, b) | ||
| 59 | # define timer_expired_fast(current, future) timer_expired32(current, future) | ||
| 60 | typedef uint32_t fast_timer_t; | ||
| 61 | fast_timer_t inline timer_read_fast(void) { return timer_read32(); } | ||
| 62 | fast_timer_t inline timer_elapsed_fast(fast_timer_t last) { return timer_elapsed32(last); } | ||
| 63 | #endif | ||
| 64 | |||
| 45 | #ifdef __cplusplus | 65 | #ifdef __cplusplus |
| 46 | } | 66 | } |
| 47 | #endif | 67 | #endif |
diff --git a/tmk_core/common/usb_util.c b/tmk_core/common/usb_util.c index d4134a044..dd1deeaa1 100644 --- a/tmk_core/common/usb_util.c +++ b/tmk_core/common/usb_util.c | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include "quantum.h" | 16 | #include "quantum.h" |
| 17 | #include "usb_util.h" | 17 | #include "usb_util.h" |
| 18 | 18 | ||
| 19 | __attribute__((weak)) void usb_disable(void) {} | 19 | __attribute__((weak)) void usb_disconnect(void) {} |
| 20 | __attribute__((weak)) bool usb_connected_state(void) { return true; } | 20 | __attribute__((weak)) bool usb_connected_state(void) { return true; } |
| 21 | __attribute__((weak)) bool usb_vbus_state(void) { | 21 | __attribute__((weak)) bool usb_vbus_state(void) { |
| 22 | #ifdef USB_VBUS_PIN | 22 | #ifdef USB_VBUS_PIN |
diff --git a/tmk_core/common/usb_util.h b/tmk_core/common/usb_util.h index 4ebedb1e7..13db9fbfb 100644 --- a/tmk_core/common/usb_util.h +++ b/tmk_core/common/usb_util.h | |||
| @@ -17,6 +17,6 @@ | |||
| 17 | 17 | ||
| 18 | #include <stdbool.h> | 18 | #include <stdbool.h> |
| 19 | 19 | ||
| 20 | void usb_disable(void); | 20 | void usb_disconnect(void); |
| 21 | bool usb_connected_state(void); | 21 | bool usb_connected_state(void); |
| 22 | bool usb_vbus_state(void); | 22 | bool usb_vbus_state(void); |
