diff options
Diffstat (limited to 'quantum')
151 files changed, 2363 insertions, 8097 deletions
diff --git a/quantum/action.c b/quantum/action.c index be135f18f2..ceaaa551f5 100644 --- a/quantum/action.c +++ b/quantum/action.c @@ -18,6 +18,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #include "keycode.h"  #include "keyboard.h"  #include "mousekey.h" +#include "programmable_button.h"  #include "command.h"  #include "led.h"  #include "action_layer.h" @@ -26,6 +27,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #include "action_util.h"  #include "action.h"  #include "wait.h" +#include "keycode_config.h"  #ifdef BACKLIGHT_ENABLE  #    include "backlight.h" @@ -86,19 +88,21 @@ void action_exec(keyevent_t event) {      keyrecord_t record = {.event = event};  #ifndef NO_ACTION_ONESHOT +    if (!keymap_config.oneshot_disable) {  #    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) -    if (has_oneshot_layer_timed_out()) { -        clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); -    } -    if (has_oneshot_mods_timed_out()) { -        clear_oneshot_mods(); -    } +        if (has_oneshot_layer_timed_out()) { +            clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); +        } +        if (has_oneshot_mods_timed_out()) { +            clear_oneshot_mods(); +        }  #        ifdef SWAP_HANDS_ENABLE -    if (has_oneshot_swaphands_timed_out()) { -        clear_oneshot_swaphands(); -    } +        if (has_oneshot_swaphands_timed_out()) { +            clear_oneshot_swaphands(); +        }  #        endif  #    endif +    }  #endif  #ifndef NO_ACTION_TAPPING @@ -194,7 +198,7 @@ void process_record(keyrecord_t *record) {      if (!process_record_quantum(record)) {  #ifndef NO_ACTION_ONESHOT -        if (is_oneshot_layer_active() && record->event.pressed) { +        if (is_oneshot_layer_active() && record->event.pressed && !keymap_config.oneshot_disable) {              clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);          }  #endif @@ -259,7 +263,7 @@ void process_action(keyrecord_t *record, action_t action) {  #    ifdef SWAP_HANDS_ENABLE          && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)  #    endif -    ) { +        && !keymap_config.oneshot_disable) {          clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);          do_release_oneshot = !is_oneshot_layer_active();      } @@ -273,8 +277,8 @@ void process_action(keyrecord_t *record, action_t action) {              if (event.pressed) {                  if (mods) {                      if (IS_MOD(action.key.code) || action.key.code == KC_NO) { -                        // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless. -                        // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT). +                        // e.g. LSFT(KC_LEFT_GUI): we don't want the LSFT to be weak as it would make it useless. +                        // This also makes LSFT(KC_LEFT_GUI) behave exactly the same as LGUI(KC_LEFT_SHIFT).                          // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO).                          add_mods(mods);                      } else { @@ -303,41 +307,68 @@ void process_action(keyrecord_t *record, action_t action) {  #    ifndef NO_ACTION_ONESHOT                  case MODS_ONESHOT:                      // Oneshot modifier -                    if (event.pressed) { -                        if (tap_count == 0) { -                            dprint("MODS_TAP: Oneshot: 0\n"); -                            register_mods(mods | get_oneshot_mods()); -                        } else if (tap_count == 1) { -                            dprint("MODS_TAP: Oneshot: start\n"); -                            set_oneshot_mods(mods | get_oneshot_mods()); -#        if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 -                        } else if (tap_count == ONESHOT_TAP_TOGGLE) { -                            dprint("MODS_TAP: Toggling oneshot"); -                            clear_oneshot_mods(); -                            set_oneshot_locked_mods(mods); -                            register_mods(mods); -#        endif +                    if (keymap_config.oneshot_disable) { +                        if (event.pressed) { +                            if (mods) { +                                if (IS_MOD(action.key.code) || action.key.code == KC_NO) { +                                    // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless. +                                    // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT). +                                    // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO). +                                    add_mods(mods); +                                } else { +                                    add_weak_mods(mods); +                                } +                                send_keyboard_report(); +                            } +                            register_code(action.key.code);                          } else { -                            register_mods(mods | get_oneshot_mods()); +                            unregister_code(action.key.code); +                            if (mods) { +                                if (IS_MOD(action.key.code) || action.key.code == KC_NO) { +                                    del_mods(mods); +                                } else { +                                    del_weak_mods(mods); +                                } +                                send_keyboard_report(); +                            }                          }                      } else { -                        if (tap_count == 0) { -                            clear_oneshot_mods(); -                            unregister_mods(mods); -                        } else if (tap_count == 1) { -                            // Retain Oneshot mods +                        if (event.pressed) { +                            if (tap_count == 0) { +                                dprint("MODS_TAP: Oneshot: 0\n"); +                                register_mods(mods | get_oneshot_mods()); +                            } else if (tap_count == 1) { +                                dprint("MODS_TAP: Oneshot: start\n"); +                                set_oneshot_mods(mods | get_oneshot_mods());  #        if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 -                            if (mods & get_mods()) { -                                clear_oneshot_locked_mods(); +                            } else if (tap_count == ONESHOT_TAP_TOGGLE) { +                                dprint("MODS_TAP: Toggling oneshot");                                  clear_oneshot_mods(); -                                unregister_mods(mods); -                            } -                        } else if (tap_count == ONESHOT_TAP_TOGGLE) { -                            // Toggle Oneshot Layer +                                set_oneshot_locked_mods(mods); +                                register_mods(mods);  #        endif +                            } else { +                                register_mods(mods | get_oneshot_mods()); +                            }                          } else { -                            clear_oneshot_mods(); -                            unregister_mods(mods); +                            if (tap_count == 0) { +                                clear_oneshot_mods(); +                                unregister_mods(mods); +                            } else if (tap_count == 1) { +                                // Retain Oneshot mods +#        if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 +                                if (mods & get_mods()) { +                                    clear_oneshot_locked_mods(); +                                    clear_oneshot_mods(); +                                    unregister_mods(mods); +                                } +                            } else if (tap_count == ONESHOT_TAP_TOGGLE) { +                                // Toggle Oneshot Layer +#        endif +                            } else { +                                clear_oneshot_mods(); +                                unregister_mods(mods); +                            }                          }                      }                      break; @@ -379,7 +410,7 @@ void process_action(keyrecord_t *record, action_t action) {                      } else {                          if (tap_count > 0) {                              dprint("MODS_TAP: Tap: unregister_code\n"); -                            if (action.layer_tap.code == KC_CAPS) { +                            if (action.layer_tap.code == KC_CAPS_LOCK) {                                  wait_ms(TAP_HOLD_CAPS_DELAY);                              } else {                                  wait_ms(TAP_CODE_DELAY); @@ -522,39 +553,47 @@ void process_action(keyrecord_t *record, action_t action) {  #        ifndef NO_ACTION_ONESHOT                  case OP_ONESHOT:                      // Oneshot modifier -#            if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 -                    do_release_oneshot = false; -                    if (event.pressed) { -                        del_mods(get_oneshot_locked_mods()); -                        if (get_oneshot_layer_state() == ONESHOT_TOGGLED) { -                            reset_oneshot_layer(); -                            layer_off(action.layer_tap.val); -                            break; -                        } else if (tap_count < ONESHOT_TAP_TOGGLE) { +                    if (keymap_config.oneshot_disable) { +                        if (event.pressed) {                              layer_on(action.layer_tap.val); -                            set_oneshot_layer(action.layer_tap.val, ONESHOT_START); +                        } else { +                            layer_off(action.layer_tap.val);                          }                      } else { -                        add_mods(get_oneshot_locked_mods()); -                        if (tap_count >= ONESHOT_TAP_TOGGLE) { -                            reset_oneshot_layer(); -                            clear_oneshot_locked_mods(); -                            set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED); +#            if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 +                        do_release_oneshot = false; +                        if (event.pressed) { +                            del_mods(get_oneshot_locked_mods()); +                            if (get_oneshot_layer_state() == ONESHOT_TOGGLED) { +                                reset_oneshot_layer(); +                                layer_off(action.layer_tap.val); +                                break; +                            } else if (tap_count < ONESHOT_TAP_TOGGLE) { +                                layer_on(action.layer_tap.val); +                                set_oneshot_layer(action.layer_tap.val, ONESHOT_START); +                            }                          } else { -                            clear_oneshot_layer_state(ONESHOT_PRESSED); +                            add_mods(get_oneshot_locked_mods()); +                            if (tap_count >= ONESHOT_TAP_TOGGLE) { +                                reset_oneshot_layer(); +                                clear_oneshot_locked_mods(); +                                set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED); +                            } else { +                                clear_oneshot_layer_state(ONESHOT_PRESSED); +                            }                          } -                    }  #            else -                    if (event.pressed) { -                        layer_on(action.layer_tap.val); -                        set_oneshot_layer(action.layer_tap.val, ONESHOT_START); -                    } else { -                        clear_oneshot_layer_state(ONESHOT_PRESSED); -                        if (tap_count > 1) { -                            clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); +                        if (event.pressed) { +                            layer_on(action.layer_tap.val); +                            set_oneshot_layer(action.layer_tap.val, ONESHOT_START); +                        } else { +                            clear_oneshot_layer_state(ONESHOT_PRESSED); +                            if (tap_count > 1) { +                                clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); +                            }                          } -                    }  #            endif +                    }                      break;  #        endif                  default: @@ -570,7 +609,7 @@ void process_action(keyrecord_t *record, action_t action) {                      } else {                          if (tap_count > 0) {                              dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n"); -                            if (action.layer_tap.code == KC_CAPS) { +                            if (action.layer_tap.code == KC_CAPS_LOCK) {                                  wait_ms(TAP_HOLD_CAPS_DELAY);                              } else {                                  wait_ms(TAP_CODE_DELAY); @@ -747,44 +786,45 @@ void register_code(uint8_t code) {          return;      }  #ifdef LOCKING_SUPPORT_ENABLE -    else if (KC_LOCKING_CAPS == code) { +    else if (KC_LOCKING_CAPS_LOCK == code) {  #    ifdef LOCKING_RESYNC_ENABLE          // Resync: ignore if caps lock already is on          if (host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK)) return;  #    endif -        add_key(KC_CAPSLOCK); +        add_key(KC_CAPS_LOCK);          send_keyboard_report();          wait_ms(100); -        del_key(KC_CAPSLOCK); +        del_key(KC_CAPS_LOCK);          send_keyboard_report();      } -    else if (KC_LOCKING_NUM == code) { +    else if (KC_LOCKING_NUM_LOCK == code) {  #    ifdef LOCKING_RESYNC_ENABLE          if (host_keyboard_leds() & (1 << USB_LED_NUM_LOCK)) return;  #    endif -        add_key(KC_NUMLOCK); +        add_key(KC_NUM_LOCK);          send_keyboard_report();          wait_ms(100); -        del_key(KC_NUMLOCK); +        del_key(KC_NUM_LOCK);          send_keyboard_report();      } -    else if (KC_LOCKING_SCROLL == code) { +    else if (KC_LOCKING_SCROLL_LOCK == code) {  #    ifdef LOCKING_RESYNC_ENABLE          if (host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK)) return;  #    endif -        add_key(KC_SCROLLLOCK); +        add_key(KC_SCROLL_LOCK);          send_keyboard_report();          wait_ms(100); -        del_key(KC_SCROLLLOCK); +        del_key(KC_SCROLL_LOCK);          send_keyboard_report();      }  #endif -    else if IS_KEY (code) { -        // TODO: should push command_proc out of this block? -        if (command_proc(code)) return; +    else if +        IS_KEY(code) { +            // TODO: should push command_proc out of this block? +            if (command_proc(code)) return;  #ifndef NO_ACTION_ONESHOT  /* TODO: remove @@ -801,33 +841,35 @@ void register_code(uint8_t code) {          } else  */  #endif -        { -            // Force a new key press if the key is already pressed -            // without this, keys with the same keycode, but different -            // modifiers will be reported incorrectly, see issue #1708 -            if (is_key_pressed(keyboard_report, code)) { -                del_key(code); +            { +                // Force a new key press if the key is already pressed +                // without this, keys with the same keycode, but different +                // modifiers will be reported incorrectly, see issue #1708 +                if (is_key_pressed(keyboard_report, code)) { +                    del_key(code); +                    send_keyboard_report(); +                } +                add_key(code);                  send_keyboard_report();              } -            add_key(code); +        } +    else if +        IS_MOD(code) { +            add_mods(MOD_BIT(code));              send_keyboard_report();          } -    } else if IS_MOD (code) { -        add_mods(MOD_BIT(code)); -        send_keyboard_report(); -    }  #ifdef EXTRAKEY_ENABLE -    else if IS_SYSTEM (code) { -        host_system_send(KEYCODE2SYSTEM(code)); -    } else if IS_CONSUMER (code) { -        host_consumer_send(KEYCODE2CONSUMER(code)); -    } +    else if +        IS_SYSTEM(code) { host_system_send(KEYCODE2SYSTEM(code)); } +    else if +        IS_CONSUMER(code) { host_consumer_send(KEYCODE2CONSUMER(code)); }  #endif  #ifdef MOUSEKEY_ENABLE -    else if IS_MOUSEKEY (code) { -        mousekey_on(code); -        mousekey_send(); -    } +    else if +        IS_MOUSEKEY(code) { +            mousekey_on(code); +            mousekey_send(); +        }  #endif  } @@ -840,54 +882,58 @@ void unregister_code(uint8_t code) {          return;      }  #ifdef LOCKING_SUPPORT_ENABLE -    else if (KC_LOCKING_CAPS == code) { +    else if (KC_LOCKING_CAPS_LOCK == code) {  #    ifdef LOCKING_RESYNC_ENABLE          // Resync: ignore if caps lock already is off          if (!(host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK))) return;  #    endif -        add_key(KC_CAPSLOCK); +        add_key(KC_CAPS_LOCK);          send_keyboard_report(); -        del_key(KC_CAPSLOCK); +        del_key(KC_CAPS_LOCK);          send_keyboard_report();      } -    else if (KC_LOCKING_NUM == code) { +    else if (KC_LOCKING_NUM_LOCK == code) {  #    ifdef LOCKING_RESYNC_ENABLE          if (!(host_keyboard_leds() & (1 << USB_LED_NUM_LOCK))) return;  #    endif -        add_key(KC_NUMLOCK); +        add_key(KC_NUM_LOCK);          send_keyboard_report(); -        del_key(KC_NUMLOCK); +        del_key(KC_NUM_LOCK);          send_keyboard_report();      } -    else if (KC_LOCKING_SCROLL == code) { +    else if (KC_LOCKING_SCROLL_LOCK == code) {  #    ifdef LOCKING_RESYNC_ENABLE          if (!(host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK))) return;  #    endif -        add_key(KC_SCROLLLOCK); +        add_key(KC_SCROLL_LOCK);          send_keyboard_report(); -        del_key(KC_SCROLLLOCK); +        del_key(KC_SCROLL_LOCK);          send_keyboard_report();      }  #endif -    else if IS_KEY (code) { -        del_key(code); -        send_keyboard_report(); -    } else if IS_MOD (code) { -        del_mods(MOD_BIT(code)); -        send_keyboard_report(); -    } else if IS_SYSTEM (code) { -        host_system_send(0); -    } else if IS_CONSUMER (code) { -        host_consumer_send(0); -    } +    else if +        IS_KEY(code) { +            del_key(code); +            send_keyboard_report(); +        } +    else if +        IS_MOD(code) { +            del_mods(MOD_BIT(code)); +            send_keyboard_report(); +        } +    else if +        IS_SYSTEM(code) { host_system_send(0); } +    else if +        IS_CONSUMER(code) { host_consumer_send(0); }  #ifdef MOUSEKEY_ENABLE -    else if IS_MOUSEKEY (code) { -        mousekey_off(code); -        mousekey_send(); -    } +    else if +        IS_MOUSEKEY(code) { +            mousekey_off(code); +            mousekey_send(); +        }  #endif  } @@ -906,9 +952,9 @@ void tap_code_delay(uint8_t code, uint16_t delay) {  /** \brief Tap a keycode with the default delay.   * - * \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. + * \param code The basic keycode to tap. If `code` is `KC_CAPS_LOCK`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined.   */ -void tap_code(uint8_t code) { tap_code_delay(code, code == KC_CAPS ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); } +void tap_code(uint8_t code) { tap_code_delay(code, code == KC_CAPS_LOCK ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); }  /** \brief Adds the given physically pressed modifiers and sends a keyboard report immediately.   * @@ -988,6 +1034,10 @@ void clear_keyboard_but_mods_and_keys() {      mousekey_clear();      mousekey_send();  #endif +#ifdef PROGRAMMABLE_BUTTON_ENABLE +    programmable_button_clear(); +    programmable_button_send(); +#endif  }  /** \brief Utilities for actions. (FIXME: Needs better description) @@ -1028,7 +1078,7 @@ bool is_tap_action(action_t action) {          case ACT_LAYER_TAP:          case ACT_LAYER_TAP_EXT:              switch (action.layer_tap.code) { -                case KC_NO ... KC_RGUI: +                case KC_NO ... KC_RIGHT_GUI:                  case OP_TAP_TOGGLE:                  case OP_ONESHOT:                      return true; @@ -1036,7 +1086,7 @@ bool is_tap_action(action_t action) {              return false;          case ACT_SWAP_HANDS:              switch (action.swap.code) { -                case KC_NO ... KC_RGUI: +                case KC_NO ... KC_RIGHT_GUI:                  case OP_SH_TAP_TOGGLE:                      return true;              } diff --git a/quantum/action.h b/quantum/action.h index 8a357ded87..b562f18c5b 100644 --- a/quantum/action.h +++ b/quantum/action.h @@ -88,7 +88,7 @@ extern bool disable_action_cache;  /* Code for handling one-handed key modifiers. */  #ifdef SWAP_HANDS_ENABLE -extern bool                   swap_hands; +extern bool           swap_hands;  extern const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS];  #    if (MATRIX_COLS <= 8)  typedef uint8_t swap_state_row_t; diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c index 36839f9faf..60e56fb811 100644 --- a/quantum/action_tapping.c +++ b/quantum/action_tapping.c @@ -18,11 +18,11 @@  #    define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed)  #    define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)  #    define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k))) -#ifndef COMBO_ENABLE -#    define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key))) -#else -#    define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key)) && tapping_key.keycode == r->keycode) -#endif +#    ifndef COMBO_ENABLE +#        define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key))) +#    else +#        define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key)) && tapping_key.keycode == r->keycode) +#    endif  __attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { return TAPPING_TERM; } @@ -212,11 +212,15 @@ bool process_tapping(keyrecord_t *keyp) {                      if (tapping_key.tap.count > 1) {                          debug("Tapping: Start new tap with releasing last tap(>1).\n");                          // unregister key -                        process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false, -#ifdef COMBO_ENABLE -                                .keycode = tapping_key.keycode, -#endif -                                }); +                        process_record(&(keyrecord_t){ +                            .tap           = tapping_key.tap, +                            .event.key     = tapping_key.event.key, +                            .event.time    = event.time, +                            .event.pressed = false, +#    ifdef COMBO_ENABLE +                            .keycode = tapping_key.keycode, +#    endif +                        });                      } else {                          debug("Tapping: Start while last tap(1).\n");                      } @@ -254,11 +258,15 @@ bool process_tapping(keyrecord_t *keyp) {                      if (tapping_key.tap.count > 1) {                          debug("Tapping: Start new tap with releasing last timeout tap(>1).\n");                          // unregister key -                        process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false, -#ifdef COMBO_ENABLE -                                .keycode = tapping_key.keycode, -#endif -                                }); +                        process_record(&(keyrecord_t){ +                            .tap           = tapping_key.tap, +                            .event.key     = tapping_key.event.key, +                            .event.time    = event.time, +                            .event.pressed = false, +#    ifdef COMBO_ENABLE +                            .keycode = tapping_key.keycode, +#    endif +                        });                      } else {                          debug("Tapping: Start while last timeout tap(1).\n");                      } diff --git a/quantum/action_util.c b/quantum/action_util.c index 9a85bd5040..78e02aec18 100644 --- a/quantum/action_util.c +++ b/quantum/action_util.c @@ -170,7 +170,7 @@ void reset_oneshot_layer(void) {  void clear_oneshot_layer_state(oneshot_fullfillment_t state) {      uint8_t start_state = oneshot_layer_data;      oneshot_layer_data &= ~state; -    if ((!get_oneshot_layer_state() && start_state != oneshot_layer_data) || keymap_config.oneshot_disable) { +    if ((!get_oneshot_layer_state() && start_state != oneshot_layer_data) && !keymap_config.oneshot_disable) {          layer_off(get_oneshot_layer());          reset_oneshot_layer();      } @@ -189,6 +189,7 @@ void oneshot_set(bool active) {      if (keymap_config.oneshot_disable != active) {          keymap_config.oneshot_disable = active;          eeconfig_update_keymap(keymap_config.raw); +        clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);          dprintf("Oneshot: active: %d\n", active);      }  } diff --git a/quantum/api.c b/quantum/api.c deleted file mode 100644 index 1685744589..0000000000 --- a/quantum/api.c +++ /dev/null @@ -1,182 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include "api.h" -#include "quantum.h" - -void dword_to_bytes(uint32_t dword, uint8_t* bytes) { -    bytes[0] = (dword >> 24) & 0xFF; -    bytes[1] = (dword >> 16) & 0xFF; -    bytes[2] = (dword >> 8) & 0xFF; -    bytes[3] = (dword >> 0) & 0xFF; -} - -uint32_t bytes_to_dword(uint8_t* bytes, uint8_t index) { return ((uint32_t)bytes[index + 0] << 24) | ((uint32_t)bytes[index + 1] << 16) | ((uint32_t)bytes[index + 2] << 8) | (uint32_t)bytes[index + 3]; } - -__attribute__((weak)) bool process_api_quantum(uint8_t length, uint8_t* data) { return process_api_keyboard(length, data); } - -__attribute__((weak)) bool process_api_keyboard(uint8_t length, uint8_t* data) { return process_api_user(length, data); } - -__attribute__((weak)) bool process_api_user(uint8_t length, uint8_t* data) { return true; } - -void process_api(uint16_t length, uint8_t* data) { -    // SEND_STRING("\nRX: "); -    // for (uint8_t i = 0; i < length; i++) { -    //     send_byte(data[i]); -    //     SEND_STRING(" "); -    // } -    if (!process_api_quantum(length, data)) return; - -    switch (data[0]) { -        case MT_SET_DATA: -            switch (data[1]) { -                case DT_DEFAULT_LAYER: { -                    eeconfig_update_default_layer(data[2]); -                    default_layer_set((uint32_t)(data[2])); -                    break; -                } -                case DT_KEYMAP_OPTIONS: { -                    eeconfig_update_keymap(data[2]); -                    break; -                } -                case DT_RGBLIGHT: { -#ifdef RGBLIGHT_ENABLE -                    uint32_t rgblight = bytes_to_dword(data, 2); -                    eeconfig_update_rgblight(rgblight); -#endif -                    break; -                } -            } -        case MT_GET_DATA: -            switch (data[1]) { -                case DT_HANDSHAKE: { -                    MT_GET_DATA_ACK(DT_HANDSHAKE, NULL, 0); -                    break; -                } -                case DT_DEBUG: { -                    uint8_t debug_bytes[1] = {eeprom_read_byte(EECONFIG_DEBUG)}; -                    MT_GET_DATA_ACK(DT_DEBUG, debug_bytes, 1); -                    break; -                } -                case DT_DEFAULT_LAYER: { -                    uint8_t default_bytes[1] = {eeprom_read_byte(EECONFIG_DEFAULT_LAYER)}; -                    MT_GET_DATA_ACK(DT_DEFAULT_LAYER, default_bytes, 1); -                    break; -                } -                case DT_CURRENT_LAYER: { -                    uint8_t layer_state_bytes[4]; -                    dword_to_bytes(layer_state, layer_state_bytes); -                    MT_GET_DATA_ACK(DT_CURRENT_LAYER, layer_state_bytes, 4); -                    break; -                } -                case DT_AUDIO: { -#ifdef AUDIO_ENABLE -                    uint8_t audio_bytes[1] = {eeprom_read_byte(EECONFIG_AUDIO)}; -                    MT_GET_DATA_ACK(DT_AUDIO, audio_bytes, 1); -#else -                    MT_GET_DATA_ACK(DT_AUDIO, NULL, 0); -#endif -                    break; -                } -                case DT_BACKLIGHT: { -#ifdef BACKLIGHT_ENABLE -                    uint8_t backlight_bytes[1] = {eeprom_read_byte(EECONFIG_BACKLIGHT)}; -                    MT_GET_DATA_ACK(DT_BACKLIGHT, backlight_bytes, 1); -#else -                    MT_GET_DATA_ACK(DT_BACKLIGHT, NULL, 0); -#endif -                    break; -                } -                case DT_RGBLIGHT: { -#ifdef RGBLIGHT_ENABLE -                    uint8_t rgblight_bytes[4]; -                    dword_to_bytes(eeconfig_read_rgblight(), rgblight_bytes); -                    MT_GET_DATA_ACK(DT_RGBLIGHT, rgblight_bytes, 4); -#else -                    MT_GET_DATA_ACK(DT_RGBLIGHT, NULL, 0); -#endif -                    break; -                } -                case DT_KEYMAP_OPTIONS: { -                    uint8_t keymap_bytes[1] = {eeconfig_read_keymap()}; -                    MT_GET_DATA_ACK(DT_KEYMAP_OPTIONS, keymap_bytes, 1); -                    break; -                } -                case DT_KEYMAP_SIZE: { -                    uint8_t keymap_size[2] = {MATRIX_ROWS, MATRIX_COLS}; -                    MT_GET_DATA_ACK(DT_KEYMAP_SIZE, keymap_size, 2); -                    break; -                } -                // This may be too much -                // case DT_KEYMAP: { -                //     uint8_t keymap_data[MATRIX_ROWS * MATRIX_COLS * 4 + 3]; -                //     keymap_data[0] = data[2]; -                //     keymap_data[1] = MATRIX_ROWS; -                //     keymap_data[2] = MATRIX_COLS; -                //     for (int i = 0; i < MATRIX_ROWS; i++) { -                //         for (int j = 0; j < MATRIX_COLS; j++) { -                //             keymap_data[3 + (i*MATRIX_COLS*2) + (j*2)] = pgm_read_word(&keymaps[data[2]][i][j]) >> 8; -                //             keymap_data[3 + (i*MATRIX_COLS*2) + (j*2) + 1] = pgm_read_word(&keymaps[data[2]][i][j]) & 0xFF; -                //         } -                //     } -                //     MT_GET_DATA_ACK(DT_KEYMAP, keymap_data, MATRIX_ROWS * MATRIX_COLS * 4 + 3); -                //     // uint8_t keymap_data[5]; -                //     // keymap_data[0] = data[2]; -                //     // keymap_data[1] = data[3]; -                //     // keymap_data[2] = data[4]; -                //     // keymap_data[3] = pgm_read_word(&keymaps[data[2]][data[3]][data[4]]) >> 8; -                //     // keymap_data[4] = pgm_read_word(&keymaps[data[2]][data[3]][data[4]]) & 0xFF; - -                //     // MT_GET_DATA_ACK(DT_KEYMAP, keymap_data, 5); -                //     break; -                // } -                default: -                    break; -            } -            break; -        case MT_SET_DATA_ACK: -        case MT_GET_DATA_ACK: -            break; -        case MT_SEND_DATA: -            break; -        case MT_SEND_DATA_ACK: -            break; -        case MT_EXE_ACTION: -            break; -        case MT_EXE_ACTION_ACK: -            break; -        case MT_TYPE_ERROR: -            break; -        default:;  // command not recognised -            SEND_BYTES(MT_TYPE_ERROR, DT_NONE, data, length); -            break; - -            // #ifdef RGBLIGHT_ENABLE -            // case 0x27: ; // RGB LED functions -            //     switch (*data++) { -            //         case 0x00: ; // Update HSV -            //             rgblight_sethsv((data[0] << 8 | data[1]) % 360, data[2], data[3]); -            //             break; -            //         case 0x01: ; // Update RGB -            //             break; -            //         case 0x02: ; // Update mode -            //             rgblight_mode(data[0]); -            //             break; -            //     } -            //     break; -            // #endif -    } -} diff --git a/quantum/api.h b/quantum/api.h deleted file mode 100644 index 0a30e9d6cc..0000000000 --- a/quantum/api.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#pragma once - -#ifdef __AVR__ -#    include "lufa.h" -#endif - -enum MESSAGE_TYPE { -    MT_GET_DATA       = 0x10,  // Get data from keyboard -    MT_GET_DATA_ACK   = 0x11,  // returned data to process (ACK) -    MT_SET_DATA       = 0x20,  // Set data on keyboard -    MT_SET_DATA_ACK   = 0x21,  // returned data to confirm (ACK) -    MT_SEND_DATA      = 0x30,  // Sending data/action from keyboard -    MT_SEND_DATA_ACK  = 0x31,  // returned data/action confirmation (ACK) -    MT_EXE_ACTION     = 0x40,  // executing actions on keyboard -    MT_EXE_ACTION_ACK = 0x41,  // return confirmation/value (ACK) -    MT_TYPE_ERROR     = 0x80   // type not recognised (ACK) -}; - -enum DATA_TYPE { DT_NONE = 0x00, DT_HANDSHAKE, DT_DEFAULT_LAYER, DT_CURRENT_LAYER, DT_KEYMAP_OPTIONS, DT_BACKLIGHT, DT_RGBLIGHT, DT_UNICODE, DT_DEBUG, DT_AUDIO, DT_QUANTUM_ACTION, DT_KEYBOARD_ACTION, DT_USER_ACTION, DT_KEYMAP_SIZE, DT_KEYMAP }; - -void     dword_to_bytes(uint32_t dword, uint8_t* bytes); -uint32_t bytes_to_dword(uint8_t* bytes, uint8_t index); - -#define MT_GET_DATA(data_type, data, length) SEND_BYTES(MT_GET_DATA, data_type, data, length) -#define MT_GET_DATA_ACK(data_type, data, length) SEND_BYTES(MT_GET_DATA_ACK, data_type, data, length) -#define MT_SET_DATA(data_type, data, length) SEND_BYTES(MT_SET_DATA, data_type, data, length) -#define MT_SET_DATA_ACK(data_type, data, length) SEND_BYTES(MT_SET_DATA_ACK, data_type, data, length) -#define MT_SEND_DATA(data_type, data, length) SEND_BYTES(MT_SEND_DATA, data_type, data, length) -#define MT_SEND_DATA_ACK(data_type, data, length) SEND_BYTES(MT_SEND_DATA_ACK, data_type, data, length) -#define MT_EXE_ACTION(data_type, data, length) SEND_BYTES(MT_EXE_ACTION, data_type, data, length) -#define MT_EXE_ACTION_ACK(data_type, data, length) SEND_BYTES(MT_EXE_ACTION_ACK, data_type, data, length) - -void process_api(uint16_t length, uint8_t* data); - -__attribute__((weak)) bool process_api_quantum(uint8_t length, uint8_t* data); - -__attribute__((weak)) bool process_api_keyboard(uint8_t length, uint8_t* data); - -__attribute__((weak)) bool process_api_user(uint8_t length, uint8_t* data); diff --git a/quantum/api/api_sysex.c b/quantum/api/api_sysex.c deleted file mode 100644 index 07c90cf804..0000000000 --- a/quantum/api/api_sysex.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2016 Jack Humbert, Fred Sundvik - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#include "api_sysex.h" -#include "sysex_tools.h" -#include "print.h" -#include "qmk_midi.h" - -void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t* bytes, uint16_t length) { -    // SEND_STRING("\nTX: "); -    // for (uint8_t i = 0; i < length; i++) { -    //     send_byte(bytes[i]); -    //     SEND_STRING(" "); -    // } -    if (length > API_SYSEX_MAX_SIZE) { -        xprintf("Sysex msg too big %d %d %d", message_type, data_type, length); -        return; -    } - -    // The buffer size required is calculated as the following -    // API_SYSEX_MAX_SIZE is the maximum length -    // In addition to that we have a two byte message header consisting of the message_type and data_type -    // This has to be encoded with an additional overhead of one byte for every starting 7 bytes -    // We just add one extra byte in case it's not divisible by 7 -    // Then we have an unencoded header consisting of 4 bytes -    // Plus a one byte terminator -    const unsigned message_header    = 2; -    const unsigned unencoded_message = API_SYSEX_MAX_SIZE + message_header; -    const unsigned encoding_overhead = unencoded_message / 7 + 1; -    const unsigned encoded_size      = unencoded_message + encoding_overhead; -    const unsigned unencoded_header  = 4; -    const unsigned terminator        = 1; -    const unsigned buffer_size       = encoded_size + unencoded_header + terminator; -    uint8_t        buffer[encoded_size + unencoded_header + terminator]; -    // The unencoded header -    buffer[0] = 0xF0; -    buffer[1] = 0x00; -    buffer[2] = 0x00; -    buffer[3] = 0x00; - -    // We copy the message to the end of the array, this way we can do an inplace encoding, using the same -    // buffer for both input and output -    const unsigned message_size    = length + message_header; -    uint8_t*       unencoded_start = buffer + buffer_size - message_size; -    uint8_t*       ptr             = unencoded_start; -    *(ptr++)                       = message_type; -    *(ptr++)                       = data_type; -    memcpy(ptr, bytes, length); - -    unsigned encoded_length = sysex_encode(buffer + unencoded_header, unencoded_start, message_size); -    unsigned final_size     = unencoded_header + encoded_length + terminator; -    buffer[final_size - 1]  = 0xF7; -    midi_send_array(&midi_device, final_size, buffer); - -    // SEND_STRING("\nTD: "); -    // for (uint8_t i = 0; i < encoded_length + 5; i++) { -    //     send_byte(buffer[i]); -    //     SEND_STRING(" "); -    // } -} diff --git a/quantum/api/api_sysex.h b/quantum/api/api_sysex.h deleted file mode 100644 index eb0a18848d..0000000000 --- a/quantum/api/api_sysex.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#pragma once - -#include "api.h" - -#define API_SYSEX_MAX_SIZE 32 - -void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t* bytes, uint16_t length); - -#define SEND_BYTES(mt, dt, b, l) send_bytes_sysex(mt, dt, b, l) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 56b9158a1a..290d461f5a 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -26,17 +26,12 @@  #if defined(__AVR__)  #    include <avr/io.h> -#    if defined(AUDIO_DRIVER_PWM) -#        include "driver_avr_pwm.h" -#    endif  #endif -#if defined(PROTOCOL_CHIBIOS) -#    if defined(AUDIO_DRIVER_PWM) -#        include "driver_chibios_pwm.h" -#    elif defined(AUDIO_DRIVER_DAC) -#        include "driver_chibios_dac.h" -#    endif +#if defined(AUDIO_DRIVER_PWM) +#    include "audio_pwm.h" +#elif defined(AUDIO_DRIVER_DAC) +#    include "audio_dac.h"  #endif  typedef union { diff --git a/quantum/audio/driver_avr_pwm.h b/quantum/audio/driver_avr_pwm.h deleted file mode 100644 index d6eb3571da..0000000000 --- a/quantum/audio/driver_avr_pwm.h +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright 2020 Jack Humbert - * Copyright 2020 JohSchneider - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#pragma once diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c deleted file mode 100644 index df03a4558c..0000000000 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ /dev/null @@ -1,332 +0,0 @@ -/* Copyright 2016 Jack Humbert - * Copyright 2020 JohSchneider - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#if defined(__AVR__) -#    include <avr/pgmspace.h> -#    include <avr/interrupt.h> -#    include <avr/io.h> -#endif - -#include "audio.h" - -extern bool    playing_note; -extern bool    playing_melody; -extern uint8_t note_timbre; - -#define CPU_PRESCALER 8 - -/* -  Audio Driver: PWM - -  drive up to two speakers through the AVR PWM hardware-peripheral, using timer1 and/or timer3 on Atmega32U4. - -  the primary channel_1 can be connected to either pin PC4 PC5 or PC6 (the later being used by most AVR based keyboards) with a PMW signal generated by timer3 -  and an optional secondary channel_2 on either pin PB5, PB6 or PB7, with a PWM signal from timer1 - -  alternatively, the PWM pins on PORTB can be used as only/primary speaker -*/ - -#if defined(AUDIO_PIN) && (AUDIO_PIN != C4) && (AUDIO_PIN != C5) && (AUDIO_PIN != C6) && (AUDIO_PIN != B5) && (AUDIO_PIN != B6) && (AUDIO_PIN != B7) && (AUDIO_PIN != D5) -#    error "Audio feature enabled, but no suitable pin selected as AUDIO_PIN - see docs/feature_audio under the AVR settings for available options." -#endif - -#if (AUDIO_PIN == C4) || (AUDIO_PIN == C5) || (AUDIO_PIN == C6) -#    define AUDIO1_PIN_SET -#    define AUDIO1_TIMSKx TIMSK3 -#    define AUDIO1_TCCRxA TCCR3A -#    define AUDIO1_TCCRxB TCCR3B -#    define AUDIO1_ICRx ICR3 -#    define AUDIO1_WGMx0 WGM30 -#    define AUDIO1_WGMx1 WGM31 -#    define AUDIO1_WGMx2 WGM32 -#    define AUDIO1_WGMx3 WGM33 -#    define AUDIO1_CSx0 CS30 -#    define AUDIO1_CSx1 CS31 -#    define AUDIO1_CSx2 CS32 - -#    if (AUDIO_PIN == C6) -#        define AUDIO1_COMxy0 COM3A0 -#        define AUDIO1_COMxy1 COM3A1 -#        define AUDIO1_OCIExy OCIE3A -#        define AUDIO1_OCRxy OCR3A -#        define AUDIO1_PIN C6 -#        define AUDIO1_TIMERx_COMPy_vect TIMER3_COMPA_vect -#    elif (AUDIO_PIN == C5) -#        define AUDIO1_COMxy0 COM3B0 -#        define AUDIO1_COMxy1 COM3B1 -#        define AUDIO1_OCIExy OCIE3B -#        define AUDIO1_OCRxy OCR3B -#        define AUDIO1_PIN C5 -#        define AUDIO1_TIMERx_COMPy_vect TIMER3_COMPB_vect -#    elif (AUDIO_PIN == C4) -#        define AUDIO1_COMxy0 COM3C0 -#        define AUDIO1_COMxy1 COM3C1 -#        define AUDIO1_OCIExy OCIE3C -#        define AUDIO1_OCRxy OCR3C -#        define AUDIO1_PIN C4 -#        define AUDIO1_TIMERx_COMPy_vect TIMER3_COMPC_vect -#    endif -#endif - -#if defined(AUDIO_PIN) && defined(AUDIO_PIN_ALT) && (AUDIO_PIN == AUDIO_PIN_ALT) -#    error "Audio feature: AUDIO_PIN and AUDIO_PIN_ALT on the same pin makes no sense." -#endif - -#if ((AUDIO_PIN == B5) && ((AUDIO_PIN_ALT == B6) || (AUDIO_PIN_ALT == B7))) || ((AUDIO_PIN == B6) && ((AUDIO_PIN_ALT == B5) || (AUDIO_PIN_ALT == B7))) || ((AUDIO_PIN == B7) && ((AUDIO_PIN_ALT == B5) || (AUDIO_PIN_ALT == B6))) -#    error "Audio feature: PORTB as AUDIO_PIN and AUDIO_PIN_ALT at the same time is not supported." -#endif - -#if defined(AUDIO_PIN_ALT) && (AUDIO_PIN_ALT != B5) && (AUDIO_PIN_ALT != B6) && (AUDIO_PIN_ALT != B7) -#    error "Audio feature: the pin selected as AUDIO_PIN_ALT is not supported." -#endif - -#if (AUDIO_PIN == B5) || (AUDIO_PIN == B6) || (AUDIO_PIN == B7) || (AUDIO_PIN_ALT == B5) || (AUDIO_PIN_ALT == B6) || (AUDIO_PIN_ALT == B7) || (AUDIO_PIN == D5) -#    define AUDIO2_PIN_SET -#    define AUDIO2_TIMSKx TIMSK1 -#    define AUDIO2_TCCRxA TCCR1A -#    define AUDIO2_TCCRxB TCCR1B -#    define AUDIO2_ICRx ICR1 -#    define AUDIO2_WGMx0 WGM10 -#    define AUDIO2_WGMx1 WGM11 -#    define AUDIO2_WGMx2 WGM12 -#    define AUDIO2_WGMx3 WGM13 -#    define AUDIO2_CSx0 CS10 -#    define AUDIO2_CSx1 CS11 -#    define AUDIO2_CSx2 CS12 - -#    if (AUDIO_PIN == B5) || (AUDIO_PIN_ALT == B5) -#        define AUDIO2_COMxy0 COM1A0 -#        define AUDIO2_COMxy1 COM1A1 -#        define AUDIO2_OCIExy OCIE1A -#        define AUDIO2_OCRxy OCR1A -#        define AUDIO2_PIN B5 -#        define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPA_vect -#    elif (AUDIO_PIN == B6) || (AUDIO_PIN_ALT == B6) -#        define AUDIO2_COMxy0 COM1B0 -#        define AUDIO2_COMxy1 COM1B1 -#        define AUDIO2_OCIExy OCIE1B -#        define AUDIO2_OCRxy OCR1B -#        define AUDIO2_PIN B6 -#        define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPB_vect -#    elif (AUDIO_PIN == B7) || (AUDIO_PIN_ALT == B7) -#        define AUDIO2_COMxy0 COM1C0 -#        define AUDIO2_COMxy1 COM1C1 -#        define AUDIO2_OCIExy OCIE1C -#        define AUDIO2_OCRxy OCR1C -#        define AUDIO2_PIN B7 -#        define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPC_vect -#    elif (AUDIO_PIN == D5) && defined(__AVR_ATmega32A__) -#        pragma message "Audio support for ATmega32A is experimental and can cause crashes." -#        undef AUDIO2_TIMSKx -#        define AUDIO2_TIMSKx TIMSK -#        define AUDIO2_COMxy0 COM1A0 -#        define AUDIO2_COMxy1 COM1A1 -#        define AUDIO2_OCIExy OCIE1A -#        define AUDIO2_OCRxy OCR1A -#        define AUDIO2_PIN D5 -#        define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPA_vect -#    endif -#endif - -// C6 seems to be the assumed default by many existing keyboard - but sill warn the user -#if !defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) -#    pragma message "Audio feature enabled, but no suitable pin selected - see docs/feature_audio under the AVR settings for available options. Don't expect to hear anything... :-)" -// TODO: make this an error - go through the breaking-change-process and change all keyboards to the new define -#endif -// ----------------------------------------------------------------------------- - -#ifdef AUDIO1_PIN_SET -static float channel_1_frequency = 0.0f; -void         channel_1_set_frequency(float freq) { -    if (freq == 0.0f)  // a pause/rest is a valid "note" with freq=0 -    { -        // disable the output, but keep the pwm-ISR going (with the previous -        // frequency) so the audio-state keeps getting updated -        // Note: setting the duty-cycle 0 is not possible on non-inverting PWM mode - see the AVR data-sheet -        AUDIO1_TCCRxA &= ~(_BV(AUDIO1_COMxy1) | _BV(AUDIO1_COMxy0)); -        return; -    } else { -        AUDIO1_TCCRxA |= _BV(AUDIO1_COMxy1);  // enable output, PWM mode -    } - -    channel_1_frequency = freq; - -    // set pwm period -    AUDIO1_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); -    // and duty cycle -    AUDIO1_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre / 100); -} - -void channel_1_start(void) { -    // enable timer-counter ISR -    AUDIO1_TIMSKx |= _BV(AUDIO1_OCIExy); -    // enable timer-counter output -    AUDIO1_TCCRxA |= _BV(AUDIO1_COMxy1); -} - -void channel_1_stop(void) { -    // disable timer-counter ISR -    AUDIO1_TIMSKx &= ~_BV(AUDIO1_OCIExy); -    // disable timer-counter output -    AUDIO1_TCCRxA &= ~(_BV(AUDIO1_COMxy1) | _BV(AUDIO1_COMxy0)); -} -#endif - -#ifdef AUDIO2_PIN_SET -static float channel_2_frequency = 0.0f; -void         channel_2_set_frequency(float freq) { -    if (freq == 0.0f) { -        AUDIO2_TCCRxA &= ~(_BV(AUDIO2_COMxy1) | _BV(AUDIO2_COMxy0)); -        return; -    } else { -        AUDIO2_TCCRxA |= _BV(AUDIO2_COMxy1); -    } - -    channel_2_frequency = freq; - -    AUDIO2_ICRx  = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); -    AUDIO2_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre / 100); -} - -float channel_2_get_frequency(void) { return channel_2_frequency; } - -void channel_2_start(void) { -    AUDIO2_TIMSKx |= _BV(AUDIO2_OCIExy); -    AUDIO2_TCCRxA |= _BV(AUDIO2_COMxy1); -} - -void channel_2_stop(void) { -    AUDIO2_TIMSKx &= ~_BV(AUDIO2_OCIExy); -    AUDIO2_TCCRxA &= ~(_BV(AUDIO2_COMxy1) | _BV(AUDIO2_COMxy0)); -} -#endif - -void audio_driver_initialize() { -#ifdef AUDIO1_PIN_SET -    channel_1_stop(); -    setPinOutput(AUDIO1_PIN); -#endif - -#ifdef AUDIO2_PIN_SET -    channel_2_stop(); -    setPinOutput(AUDIO2_PIN); -#endif - -    // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers TCCR3A/TCCR3B, TCCR1A/TCCR1B -    // Compare Output Mode (COM3An and COM1An) = 0b00 = Normal port operation -    //   OC3A -- PC6 -    //   OC3B -- PC5 -    //   OC3C -- PC4 -    //   OC1A -- PB5 -    //   OC1B -- PB6 -    //   OC1C -- PB7 - -    // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14. Period = ICR3, Duty Cycle OCR3A) -    //   OCR3A - PC6 -    //   OCR3B - PC5 -    //   OCR3C - PC4 -    //   OCR1A - PB5 -    //   OCR1B - PB6 -    //   OCR1C - PB7 - -    // Clock Select (CS3n) = 0b010 = Clock / 8 -#ifdef AUDIO1_PIN_SET -    // initialize timer-counter -    AUDIO1_TCCRxA = (0 << AUDIO1_COMxy1) | (0 << AUDIO1_COMxy0) | (1 << AUDIO1_WGMx1) | (0 << AUDIO1_WGMx0); -    AUDIO1_TCCRxB = (1 << AUDIO1_WGMx3) | (1 << AUDIO1_WGMx2) | (0 << AUDIO1_CSx2) | (1 << AUDIO1_CSx1) | (0 << AUDIO1_CSx0); -#endif - -#ifdef AUDIO2_PIN_SET -    AUDIO2_TCCRxA = (0 << AUDIO2_COMxy1) | (0 << AUDIO2_COMxy0) | (1 << AUDIO2_WGMx1) | (0 << AUDIO2_WGMx0); -    AUDIO2_TCCRxB = (1 << AUDIO2_WGMx3) | (1 << AUDIO2_WGMx2) | (0 << AUDIO2_CSx2) | (1 << AUDIO2_CSx1) | (0 << AUDIO2_CSx0); -#endif -} - -void audio_driver_stop() { -#ifdef AUDIO1_PIN_SET -    channel_1_stop(); -#endif - -#ifdef AUDIO2_PIN_SET -    channel_2_stop(); -#endif -} - -void audio_driver_start(void) { -#ifdef AUDIO1_PIN_SET -    channel_1_start(); -    if (playing_note) { -        channel_1_set_frequency(audio_get_processed_frequency(0)); -    } -#endif - -#if !defined(AUDIO1_PIN_SET) && defined(AUDIO2_PIN_SET) -    channel_2_start(); -    if (playing_note) { -        channel_2_set_frequency(audio_get_processed_frequency(0)); -    } -#endif -} - -static volatile uint32_t isr_counter = 0; -#ifdef AUDIO1_PIN_SET -ISR(AUDIO1_TIMERx_COMPy_vect) { -    isr_counter++; -    if (isr_counter < channel_1_frequency / (CPU_PRESCALER * 8)) return; - -    isr_counter        = 0; -    bool state_changed = audio_update_state(); - -    if (!playing_note && !playing_melody) { -        channel_1_stop(); -#    ifdef AUDIO2_PIN_SET -        channel_2_stop(); -#    endif -        return; -    } - -    if (state_changed) { -        channel_1_set_frequency(audio_get_processed_frequency(0)); -#    ifdef AUDIO2_PIN_SET -        if (audio_get_number_of_active_tones() > 1) { -            channel_2_set_frequency(audio_get_processed_frequency(1)); -        } else { -            channel_2_stop(); -        } -#    endif -    } -} -#endif - -#if !defined(AUDIO1_PIN_SET) && defined(AUDIO2_PIN_SET) -ISR(AUDIO2_TIMERx_COMPy_vect) { -    isr_counter++; -    if (isr_counter < channel_2_frequency / (CPU_PRESCALER * 8)) return; - -    isr_counter        = 0; -    bool state_changed = audio_update_state(); - -    if (!playing_note && !playing_melody) { -        channel_2_stop(); -        return; -    } - -    if (state_changed) { -        channel_2_set_frequency(audio_get_processed_frequency(0)); -    } -} -#endif diff --git a/quantum/audio/driver_chibios_dac.h b/quantum/audio/driver_chibios_dac.h deleted file mode 100644 index 07cd622ead..0000000000 --- a/quantum/audio/driver_chibios_dac.h +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright 2019 Jack Humbert - * Copyright 2020 JohSchneider - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#pragma once - -#ifndef A4 -#    define A4 PAL_LINE(GPIOA, 4) -#endif -#ifndef A5 -#    define A5 PAL_LINE(GPIOA, 5) -#endif - -/** - * Size of the dac_buffer arrays. All must be the same size. - */ -#define AUDIO_DAC_BUFFER_SIZE 256U - -/** - * Highest value allowed sample value. - - * since the DAC is limited to 12 bit, the absolute max is 0xfff = 4095U; - * lower values adjust the peak-voltage aka volume down. - * adjusting this value has only an effect on a sample-buffer whose values are - * are NOT pregenerated - see square-wave - */ -#ifndef AUDIO_DAC_SAMPLE_MAX -#    define AUDIO_DAC_SAMPLE_MAX 4095U -#endif - -#if !defined(AUDIO_DAC_SAMPLE_RATE) && !defined(AUDIO_MAX_SIMULTANEOUS_TONES) && !defined(AUDIO_DAC_QUALITY_VERY_LOW) && !defined(AUDIO_DAC_QUALITY_LOW) && !defined(AUDIO_DAC_QUALITY_HIGH) && !defined(AUDIO_DAC_QUALITY_VERY_HIGH) -#    define AUDIO_DAC_QUALITY_SANE_MINIMUM -#endif - -/** - * These presets allow you to quickly switch between quality settings for - * the DAC. The sample rate and maximum number of simultaneous tones roughly - * has an inverse relationship - slightly higher sample rates may be possible. - * - * NOTE: a high sample-rate results in a higher cpu-load, which might lead to - *       (audible) discontinuities and/or starve other processes of cpu-time - *       (like RGB-led back-lighting, ...) - */ -#ifdef AUDIO_DAC_QUALITY_VERY_LOW -#    define AUDIO_DAC_SAMPLE_RATE 11025U -#    define AUDIO_MAX_SIMULTANEOUS_TONES 8 -#endif - -#ifdef AUDIO_DAC_QUALITY_LOW -#    define AUDIO_DAC_SAMPLE_RATE 22050U -#    define AUDIO_MAX_SIMULTANEOUS_TONES 4 -#endif - -#ifdef AUDIO_DAC_QUALITY_HIGH -#    define AUDIO_DAC_SAMPLE_RATE 44100U -#    define AUDIO_MAX_SIMULTANEOUS_TONES 2 -#endif - -#ifdef AUDIO_DAC_QUALITY_VERY_HIGH -#    define AUDIO_DAC_SAMPLE_RATE 88200U -#    define AUDIO_MAX_SIMULTANEOUS_TONES 1 -#endif - -#ifdef AUDIO_DAC_QUALITY_SANE_MINIMUM -/* a sane-minimum config: with a trade-off between cpu-load and tone-range - * - * the (currently) highest defined note is NOTE_B8 with 7902Hz; if we now - * aim for an even even multiple of the buffer-size, we end up with: - * ( roundUptoPow2(highest note / AUDIO_DAC_BUFFER_SIZE) * nyquist-rate * AUDIO_DAC_BUFFER_SIZE) - *                              7902/256 = 30.867        *       2      * 256 ~= 16384 - * which works out (but the 'scope shows some sampling artifacts with lower harmonics :-P) - */ -#    define AUDIO_DAC_SAMPLE_RATE 16384U -#    define AUDIO_MAX_SIMULTANEOUS_TONES 8 -#endif - -/** - * Effective bit-rate of the DAC. 44.1khz is the standard for most audio - any - * lower will sacrifice perceptible audio quality. Any higher will limit the - * number of simultaneous tones. In most situations, a tenth (1/10) of the - * sample rate is where notes become unbearable. - */ -#ifndef AUDIO_DAC_SAMPLE_RATE -#    define AUDIO_DAC_SAMPLE_RATE 44100U -#endif - -/** - * The number of tones that can be played simultaneously. If too high a value - * is used here, the keyboard will freeze and glitch-out when that many tones - * are being played. - */ -#ifndef AUDIO_MAX_SIMULTANEOUS_TONES -#    define AUDIO_MAX_SIMULTANEOUS_TONES 2 -#endif - -/** - * The default value of the DAC when not playing anything. Certain hardware - * setups may require a high (AUDIO_DAC_SAMPLE_MAX) or low (0) value here. - * Since multiple added sine waves tend to oscillate around the midpoint, - * and possibly never/rarely reach either 0 of MAX, 1/2 MAX can be a - * reasonable default value. - */ -#ifndef AUDIO_DAC_OFF_VALUE -#    define AUDIO_DAC_OFF_VALUE AUDIO_DAC_SAMPLE_MAX / 2 -#endif - -#if AUDIO_DAC_OFF_VALUE > AUDIO_DAC_SAMPLE_MAX -#    error "AUDIO_DAC: OFF_VALUE may not be larger than SAMPLE_MAX" -#endif - -/** - *user overridable sample generation/processing - */ -uint16_t dac_value_generate(void); diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c deleted file mode 100644 index db304adb87..0000000000 --- a/quantum/audio/driver_chibios_dac_additive.c +++ /dev/null @@ -1,335 +0,0 @@ -/* Copyright 2016-2019 Jack Humbert - * Copyright 2020 JohSchneider - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include "audio.h" -#include <ch.h> -#include <hal.h> - -/* -  Audio Driver: DAC - -  which utilizes the dac unit many STM32 are equipped with, to output a modulated waveform from samples stored in the dac_buffer_* array who are passed to the hardware through DMA - -  it is also possible to have a custom sample-LUT by implementing/overriding 'dac_value_generate' - -  this driver allows for multiple simultaneous tones to be played through one single channel by doing additive wave-synthesis -*/ - -#if !defined(AUDIO_PIN) -#    error "Audio feature enabled, but no suitable pin selected as AUDIO_PIN - see docs/feature_audio under 'ARM (DAC additive)' for available options." -#endif -#if defined(AUDIO_PIN_ALT) && !defined(AUDIO_PIN_ALT_AS_NEGATIVE) -#    pragma message "Audio feature: AUDIO_PIN_ALT set, but not AUDIO_PIN_ALT_AS_NEGATIVE - pin will be left unused; audio might still work though." -#endif - -#if !defined(AUDIO_PIN_ALT) -// no ALT pin defined is valid, but the c-ifs below need some value set -#    define AUDIO_PIN_ALT PAL_NOLINE -#endif - -#if !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) -#    define AUDIO_DAC_SAMPLE_WAVEFORM_SINE -#endif - -#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_SINE -/* one full sine wave over [0,2*pi], but shifted up one amplitude and left pi/4; for the samples to start at 0 - */ -static const dacsample_t dac_buffer_sine[AUDIO_DAC_BUFFER_SIZE] = { -    // 256 values, max 4095 -    0x0,   0x1,   0x2,   0x6,   0xa,   0xf,   0x16,  0x1e,  0x27,  0x32,  0x3d,  0x4a,  0x58,  0x67,  0x78,  0x89,  0x9c,  0xb0,  0xc5,  0xdb,  0xf2,  0x10a, 0x123, 0x13e, 0x159, 0x175, 0x193, 0x1b1, 0x1d1, 0x1f1, 0x212, 0x235, 0x258, 0x27c, 0x2a0, 0x2c6, 0x2ed, 0x314, 0x33c, 0x365, 0x38e, 0x3b8, 0x3e3, 0x40e, 0x43a, 0x467, 0x494, 0x4c2, 0x4f0, 0x51f, 0x54e, 0x57d, 0x5ad, 0x5dd, 0x60e, 0x63f, 0x670, 0x6a1, 0x6d3, 0x705, 0x737, 0x769, 0x79b, 0x7cd, 0x800, 0x832, 0x864, 0x896, 0x8c8, 0x8fa, 0x92c, 0x95e, 0x98f, 0x9c0, 0x9f1, 0xa22, 0xa52, 0xa82, 0xab1, 0xae0, 0xb0f, 0xb3d, 0xb6b, 0xb98, 0xbc5, 0xbf1, 0xc1c, 0xc47, 0xc71, 0xc9a, 0xcc3, 0xceb, 0xd12, 0xd39, 0xd5f, 0xd83, 0xda7, 0xdca, 0xded, 0xe0e, 0xe2e, 0xe4e, 0xe6c, 0xe8a, 0xea6, 0xec1, 0xedc, 0xef5, 0xf0d, 0xf24, 0xf3a, 0xf4f, 0xf63, 0xf76, 0xf87, 0xf98, 0xfa7, 0xfb5, 0xfc2, 0xfcd, 0xfd8, 0xfe1, 0xfe9, 0xff0, 0xff5, 0xff9, 0xffd, 0xffe, -    0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2,  0xdb,  0xc5,  0xb0,  0x9c,  0x89,  0x78,  0x67,  0x58,  0x4a,  0x3d,  0x32,  0x27,  0x1e,  0x16,  0xf,   0xa,   0x6,   0x2,   0x1}; -#endif  // AUDIO_DAC_SAMPLE_WAVEFORM_SINE -#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE -static const dacsample_t dac_buffer_triangle[AUDIO_DAC_BUFFER_SIZE] = { -    // 256 values, max 4095 -    0x0,   0x20,  0x40,  0x60,  0x80,  0xa0,  0xc0,  0xe0,  0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4a0, 0x4c0, 0x4e0, 0x500, 0x520, 0x540, 0x560, 0x580, 0x5a0, 0x5c0, 0x5e0, 0x600, 0x620, 0x640, 0x660, 0x680, 0x6a0, 0x6c0, 0x6e0, 0x700, 0x720, 0x740, 0x760, 0x780, 0x7a0, 0x7c0, 0x7e0, 0x800, 0x81f, 0x83f, 0x85f, 0x87f, 0x89f, 0x8bf, 0x8df, 0x8ff, 0x91f, 0x93f, 0x95f, 0x97f, 0x99f, 0x9bf, 0x9df, 0x9ff, 0xa1f, 0xa3f, 0xa5f, 0xa7f, 0xa9f, 0xabf, 0xadf, 0xaff, 0xb1f, 0xb3f, 0xb5f, 0xb7f, 0xb9f, 0xbbf, 0xbdf, 0xbff, 0xc1f, 0xc3f, 0xc5f, 0xc7f, 0xc9f, 0xcbf, 0xcdf, 0xcff, 0xd1f, 0xd3f, 0xd5f, 0xd7f, 0xd9f, 0xdbf, 0xddf, 0xdff, 0xe1f, 0xe3f, 0xe5f, 0xe7f, 0xe9f, 0xebf, 0xedf, 0xeff, 0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf, -    0xfff, 0xfdf, 0xfbf, 0xf9f, 0xf7f, 0xf5f, 0xf3f, 0xf1f, 0xeff, 0xedf, 0xebf, 0xe9f, 0xe7f, 0xe5f, 0xe3f, 0xe1f, 0xdff, 0xddf, 0xdbf, 0xd9f, 0xd7f, 0xd5f, 0xd3f, 0xd1f, 0xcff, 0xcdf, 0xcbf, 0xc9f, 0xc7f, 0xc5f, 0xc3f, 0xc1f, 0xbff, 0xbdf, 0xbbf, 0xb9f, 0xb7f, 0xb5f, 0xb3f, 0xb1f, 0xaff, 0xadf, 0xabf, 0xa9f, 0xa7f, 0xa5f, 0xa3f, 0xa1f, 0x9ff, 0x9df, 0x9bf, 0x99f, 0x97f, 0x95f, 0x93f, 0x91f, 0x8ff, 0x8df, 0x8bf, 0x89f, 0x87f, 0x85f, 0x83f, 0x81f, 0x800, 0x7e0, 0x7c0, 0x7a0, 0x780, 0x760, 0x740, 0x720, 0x700, 0x6e0, 0x6c0, 0x6a0, 0x680, 0x660, 0x640, 0x620, 0x600, 0x5e0, 0x5c0, 0x5a0, 0x580, 0x560, 0x540, 0x520, 0x500, 0x4e0, 0x4c0, 0x4a0, 0x480, 0x460, 0x440, 0x420, 0x400, 0x3e0, 0x3c0, 0x3a0, 0x380, 0x360, 0x340, 0x320, 0x300, 0x2e0, 0x2c0, 0x2a0, 0x280, 0x260, 0x240, 0x220, 0x200, 0x1e0, 0x1c0, 0x1a0, 0x180, 0x160, 0x140, 0x120, 0x100, 0xe0,  0xc0,  0xa0,  0x80,  0x60,  0x40,  0x20}; -#endif  // AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE -#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE -static const dacsample_t dac_buffer_square[AUDIO_DAC_BUFFER_SIZE] = { -    [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1]                     = 0,                     // first and -    [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX,  // second half -}; -#endif  // AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE -/* -// four steps: 0, 1/3, 2/3 and 1 -static const dacsample_t dac_buffer_staircase[AUDIO_DAC_BUFFER_SIZE] = { -    [0 ... AUDIO_DAC_BUFFER_SIZE/3 -1 ]                               = 0, -    [AUDIO_DAC_BUFFER_SIZE / 4 ... AUDIO_DAC_BUFFER_SIZE / 2 -1 ]     = AUDIO_DAC_SAMPLE_MAX / 3, -    [AUDIO_DAC_BUFFER_SIZE / 2 ... 3 * AUDIO_DAC_BUFFER_SIZE / 4 -1 ] = 2 * AUDIO_DAC_SAMPLE_MAX / 3, -    [3 * AUDIO_DAC_BUFFER_SIZE / 4 ... AUDIO_DAC_BUFFER_SIZE -1 ]     = AUDIO_DAC_SAMPLE_MAX, -} -*/ -#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID -static const dacsample_t dac_buffer_trapezoid[AUDIO_DAC_BUFFER_SIZE] = {0x0,   0x1f,  0x7f,  0xdf,  0x13f, 0x19f, 0x1ff, 0x25f, 0x2bf, 0x31f, 0x37f, 0x3df, 0x43f, 0x49f, 0x4ff, 0x55f, 0x5bf, 0x61f, 0x67f, 0x6df, 0x73f, 0x79f, 0x7ff, 0x85f, 0x8bf, 0x91f, 0x97f, 0x9df, 0xa3f, 0xa9f, 0xaff, 0xb5f, 0xbbf, 0xc1f, 0xc7f, 0xcdf, 0xd3f, 0xd9f, 0xdff, 0xe5f, 0xebf, 0xf1f, 0xf7f, 0xfdf, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, -                                                                        0xfff, 0xfdf, 0xf7f, 0xf1f, 0xebf, 0xe5f, 0xdff, 0xd9f, 0xd3f, 0xcdf, 0xc7f, 0xc1f, 0xbbf, 0xb5f, 0xaff, 0xa9f, 0xa3f, 0x9df, 0x97f, 0x91f, 0x8bf, 0x85f, 0x7ff, 0x79f, 0x73f, 0x6df, 0x67f, 0x61f, 0x5bf, 0x55f, 0x4ff, 0x49f, 0x43f, 0x3df, 0x37f, 0x31f, 0x2bf, 0x25f, 0x1ff, 0x19f, 0x13f, 0xdf,  0x7f,  0x1f,  0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0}; -#endif  // AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID - -static dacsample_t dac_buffer_empty[AUDIO_DAC_BUFFER_SIZE] = {AUDIO_DAC_OFF_VALUE}; - -/* keep track of the sample position for for each frequency */ -static float dac_if[AUDIO_MAX_SIMULTANEOUS_TONES] = {0.0}; - -static float   active_tones_snapshot[AUDIO_MAX_SIMULTANEOUS_TONES] = {0, 0}; -static uint8_t active_tones_snapshot_length                        = 0; - -typedef enum { -    OUTPUT_SHOULD_START, -    OUTPUT_RUN_NORMALLY, -    // path 1: wait for zero, then change/update active tones -    OUTPUT_TONES_CHANGED, -    OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE, -    // path 2: hardware should stop, wait for zero then turn output off = stop the timer -    OUTPUT_SHOULD_STOP, -    OUTPUT_REACHED_ZERO_BEFORE_OFF, -    OUTPUT_OFF, -    OUTPUT_OFF_1, -    OUTPUT_OFF_2,  // trailing off: giving the DAC two more conversion cycles until the AUDIO_DAC_OFF_VALUE reaches the output, then turn the timer off, which leaves the output at that level -    number_of_output_states -} output_states_t; -output_states_t state = OUTPUT_OFF_2; - -/** - * Generation of the waveform being passed to the callback. Declared weak so users - * can override it with their own wave-forms/noises. - */ -__attribute__((weak)) uint16_t dac_value_generate(void) { -    // DAC is running/asking for values but snapshot length is zero -> must be playing a pause -    if (active_tones_snapshot_length == 0) { -        return AUDIO_DAC_OFF_VALUE; -    } - -    /* doing additive wave synthesis over all currently playing tones = adding up -     * sine-wave-samples for each frequency, scaled by the number of active tones -     */ -    uint16_t value     = 0; -    float    frequency = 0.0f; - -    for (uint8_t i = 0; i < active_tones_snapshot_length; i++) { -        /* Note: a user implementation does not have to rely on the active_tones_snapshot, but -         * could directly query the active frequencies through audio_get_processed_frequency */ -        frequency = active_tones_snapshot[i]; - -        dac_if[i] = dac_if[i] + ((frequency * AUDIO_DAC_BUFFER_SIZE) / AUDIO_DAC_SAMPLE_RATE) * 2 / 3; -        /*Note: the 2/3 are necessary to get the correct frequencies on the -         *      DAC output (as measured with an oscilloscope), since the gpt -         *      timer runs with 3*AUDIO_DAC_SAMPLE_RATE; and the DAC callback -         *      is called twice per conversion.*/ - -        dac_if[i] = fmod(dac_if[i], AUDIO_DAC_BUFFER_SIZE); - -        // Wavetable generation/lookup -        uint16_t dac_i = (uint16_t)dac_if[i]; - -#if defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) -        value += dac_buffer_sine[dac_i] / active_tones_snapshot_length; -#elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) -        value += dac_buffer_triangle[dac_i] / active_tones_snapshot_length; -#elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) -        value += dac_buffer_trapezoid[dac_i] / active_tones_snapshot_length; -#elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) -        value += dac_buffer_square[dac_i] / active_tones_snapshot_length; -#endif -        /* -        // SINE -        value += dac_buffer_sine[dac_i] / active_tones_snapshot_length / 3; -        // TRIANGLE -        value += dac_buffer_triangle[dac_i] / active_tones_snapshot_length / 3; -        // SQUARE -        value += dac_buffer_square[dac_i] / active_tones_snapshot_length / 3; -        //NOTE: combination of these three wave-forms is more exemplary - and doesn't sound particularly good :-P -        */ - -        // STAIRS (mostly usefully as test-pattern) -        // value_avg = dac_buffer_staircase[dac_i] / active_tones_snapshot_length; -    } - -    return value; -} - -/** - * DAC streaming callback. Does all of the main computing for playing songs. - * - * Note: chibios calls this CB twice: during the 'half buffer event', and the 'full buffer event'. - */ -static void dac_end(DACDriver *dacp) { -    dacsample_t *sample_p = (dacp)->samples; - -    // work on the other half of the buffer -    if (dacIsBufferComplete(dacp)) { -        sample_p += AUDIO_DAC_BUFFER_SIZE / 2;  // 'half_index' -    } - -    for (uint8_t s = 0; s < AUDIO_DAC_BUFFER_SIZE / 2; s++) { -        if (OUTPUT_OFF <= state) { -            sample_p[s] = AUDIO_DAC_OFF_VALUE; -            continue; -        } else { -            sample_p[s] = dac_value_generate(); -        } - -        /* zero crossing (or approach, whereas zero == DAC_OFF_VALUE, which can be configured to anything from 0 to DAC_SAMPLE_MAX) -         * ============================*=*========================== AUDIO_DAC_SAMPLE_MAX -         *                          *       * -         *                        *           * -         * --------------------------------------------------------- -         *                     *                 *                  } AUDIO_DAC_SAMPLE_MAX/100 -         * --------------------------------------------------------- AUDIO_DAC_OFF_VALUE -         *                  *                       *               } AUDIO_DAC_SAMPLE_MAX/100 -         * --------------------------------------------------------- -         *               * -         * *           * -         *   *       * -         * =====*=*================================================= 0x0 -         */ -        if (((sample_p[s] + (AUDIO_DAC_SAMPLE_MAX / 100)) > AUDIO_DAC_OFF_VALUE) &&  // value approaches from below -            (sample_p[s] < (AUDIO_DAC_OFF_VALUE + (AUDIO_DAC_SAMPLE_MAX / 100)))     // or above -        ) { -            if ((OUTPUT_SHOULD_START == state) && (active_tones_snapshot_length > 0)) { -                state = OUTPUT_RUN_NORMALLY; -            } else if (OUTPUT_TONES_CHANGED == state) { -                state = OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE; -            } else if (OUTPUT_SHOULD_STOP == state) { -                state = OUTPUT_REACHED_ZERO_BEFORE_OFF; -            } -        } - -        // still 'ramping up', reset the output to OFF_VALUE until the generated values reach that value, to do a smooth handover -        if (OUTPUT_SHOULD_START == state) { -            sample_p[s] = AUDIO_DAC_OFF_VALUE; -        } - -        if ((OUTPUT_SHOULD_START == state) || (OUTPUT_REACHED_ZERO_BEFORE_OFF == state) || (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state)) { -            uint8_t active_tones         = MIN(AUDIO_MAX_SIMULTANEOUS_TONES, audio_get_number_of_active_tones()); -            active_tones_snapshot_length = 0; -            // update the snapshot - once, and only on occasion that something changed; -            // -> saves cpu cycles (?) -            for (uint8_t i = 0; i < active_tones; i++) { -                float freq = audio_get_processed_frequency(i); -                if (freq > 0) {  // disregard 'rest' notes, with valid frequency 0.0f; which would only lower the resulting waveform volume during the additive synthesis step -                    active_tones_snapshot[active_tones_snapshot_length++] = freq; -                } -            } - -            if ((0 == active_tones_snapshot_length) && (OUTPUT_REACHED_ZERO_BEFORE_OFF == state)) { -                state = OUTPUT_OFF; -            } -            if (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state) { -                state = OUTPUT_RUN_NORMALLY; -            } -        } -    } - -    // update audio internal state (note position, current_note, ...) -    if (audio_update_state()) { -        if (OUTPUT_SHOULD_STOP != state) { -            state = OUTPUT_TONES_CHANGED; -        } -    } - -    if (OUTPUT_OFF <= state) { -        if (OUTPUT_OFF_2 == state) { -            // stopping timer6 = stopping the DAC at whatever value it is currently pushing to the output = AUDIO_DAC_OFF_VALUE -            gptStopTimer(&GPTD6); -        } else { -            state++; -        } -    } -} - -static void dac_error(DACDriver *dacp, dacerror_t err) { -    (void)dacp; -    (void)err; - -    chSysHalt("DAC failure. halp"); -} - -static const GPTConfig gpt6cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE * 3, -                                   .callback  = NULL, -                                   .cr2       = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event.  */ -                                   .dier      = 0U}; - -static const DACConfig dac_conf = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT}; - -/** - * @note The DAC_TRG(0) here selects the Timer 6 TRGO event, which is triggered - * on the rising edge after 3 APB1 clock cycles, causing our gpt6cfg1.frequency - * to be a third of what we expect. - * - * Here are all the values for DAC_TRG (TSEL in the ref manual) - * TIM15_TRGO 0b011 - * TIM2_TRGO  0b100 - * TIM3_TRGO  0b001 - * TIM6_TRGO  0b000 - * TIM7_TRGO  0b010 - * EXTI9      0b110 - * SWTRIG     0b111 - */ -static const DACConversionGroup dac_conv_cfg = {.num_channels = 1U, .end_cb = dac_end, .error_cb = dac_error, .trigger = DAC_TRG(0b000)}; - -void audio_driver_initialize() { -    if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { -        palSetLineMode(A4, PAL_MODE_INPUT_ANALOG); -        dacStart(&DACD1, &dac_conf); -    } -    if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) { -        palSetLineMode(A5, PAL_MODE_INPUT_ANALOG); -        dacStart(&DACD2, &dac_conf); -    } - -    /* enable the output buffer, to directly drive external loads with no additional circuitry -     * -     * see: AN4566 Application note: Extending the DAC performance of STM32 microcontrollers -     * Note: Buffer-Off bit -> has to be set 0 to enable the output buffer -     * Note: enabling the output buffer imparts an additional dc-offset of a couple mV -     * -     * this is done here, reaching directly into the stm32 registers since chibios has not implemented BOFF handling yet -     * (see: chibios/os/hal/ports/STM32/todo.txt '- BOFF handling in DACv1.' -     */ -    DACD1.params->dac->CR &= ~DAC_CR_BOFF1; -    DACD2.params->dac->CR &= ~DAC_CR_BOFF2; - -    if (AUDIO_PIN == A4) { -        dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); -    } else if (AUDIO_PIN == A5) { -        dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); -    } - -    // no inverted/out-of-phase waveform (yet?), only pulling AUDIO_PIN_ALT to AUDIO_DAC_OFF_VALUE -#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) -    if (AUDIO_PIN_ALT == A4) { -        dacPutChannelX(&DACD1, 0, AUDIO_DAC_OFF_VALUE); -    } else if (AUDIO_PIN_ALT == A5) { -        dacPutChannelX(&DACD2, 0, AUDIO_DAC_OFF_VALUE); -    } -#endif - -    gptStart(&GPTD6, &gpt6cfg1); -} - -void audio_driver_stop(void) { state = OUTPUT_SHOULD_STOP; } - -void audio_driver_start(void) { -    gptStartContinuous(&GPTD6, 2U); - -    for (uint8_t i = 0; i < AUDIO_MAX_SIMULTANEOUS_TONES; i++) { -        dac_if[i]                = 0.0f; -        active_tones_snapshot[i] = 0.0f; -    } -    active_tones_snapshot_length = 0; -    state                        = OUTPUT_SHOULD_START; -} diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c deleted file mode 100644 index fac6513506..0000000000 --- a/quantum/audio/driver_chibios_dac_basic.c +++ /dev/null @@ -1,245 +0,0 @@ -/* Copyright 2016-2020 Jack Humbert - * Copyright 2020 JohSchneider - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include "audio.h" -#include "ch.h" -#include "hal.h" - -/* -  Audio Driver: DAC - -  which utilizes both channels of the DAC unit many STM32 are equipped with to output a modulated square-wave, from precomputed samples stored in a buffer, which is passed to the hardware through DMA - -  this driver can either be used to drive to separate speakers, wired to A4+Gnd and A5+Gnd, which allows two tones to be played simultaneously -  OR -  one speaker wired to A4+A5 with the AUDIO_PIN_ALT_AS_NEGATIVE define set - see docs/feature_audio - -*/ - -#if !defined(AUDIO_PIN) -#    pragma message "Audio feature enabled, but no suitable pin selected as AUDIO_PIN - see docs/feature_audio under 'ARM (DAC basic)' for available options." -// TODO: make this an 'error' instead; go through a breaking change, and add AUDIO_PIN A5 to all keyboards currently using AUDIO on STM32 based boards? - for now: set the define here -#    define AUDIO_PIN A5 -#endif -// check configuration for ONE speaker, connected to both DAC pins -#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) && !defined(AUDIO_PIN_ALT) -#    error "Audio feature: AUDIO_PIN_ALT_AS_NEGATIVE set, but no pin configured as AUDIO_PIN_ALT" -#endif - -#ifndef AUDIO_PIN_ALT -// no ALT pin defined is valid, but the c-ifs below need some value set -#    define AUDIO_PIN_ALT -1 -#endif - -#if !defined(AUDIO_STATE_TIMER) -#    define AUDIO_STATE_TIMER GPTD8 -#endif - -// square-wave -static const dacsample_t dac_buffer_1[AUDIO_DAC_BUFFER_SIZE] = { -    // First half is max, second half is 0 -    [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1]                     = AUDIO_DAC_SAMPLE_MAX, -    [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = 0, -}; - -// square-wave -static const dacsample_t dac_buffer_2[AUDIO_DAC_BUFFER_SIZE] = { -    // opposite of dac_buffer above -    [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1]                     = 0, -    [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX, -}; - -GPTConfig gpt6cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE, -                      .callback  = NULL, -                      .cr2       = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event.    */ -                      .dier      = 0U}; -GPTConfig gpt7cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE, -                      .callback  = NULL, -                      .cr2       = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event.    */ -                      .dier      = 0U}; - -static void gpt_audio_state_cb(GPTDriver *gptp); -GPTConfig   gptStateUpdateCfg = {.frequency = 10, -                               .callback  = gpt_audio_state_cb, -                               .cr2       = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event.    */ -                               .dier      = 0U}; - -static const DACConfig dac_conf_ch1 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT}; -static const DACConfig dac_conf_ch2 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT}; - -/** - * @note The DAC_TRG(0) here selects the Timer 6 TRGO event, which is triggered - * on the rising edge after 3 APB1 clock cycles, causing our gpt6cfg1.frequency - * to be a third of what we expect. - * - * Here are all the values for DAC_TRG (TSEL in the ref manual) - * TIM15_TRGO 0b011 - * TIM2_TRGO  0b100 - * TIM3_TRGO  0b001 - * TIM6_TRGO  0b000 - * TIM7_TRGO  0b010 - * EXTI9      0b110 - * SWTRIG     0b111 - */ -static const DACConversionGroup dac_conv_grp_ch1 = {.num_channels = 1U, .trigger = DAC_TRG(0b000)}; -static const DACConversionGroup dac_conv_grp_ch2 = {.num_channels = 1U, .trigger = DAC_TRG(0b010)}; - -void channel_1_start(void) { -    gptStart(&GPTD6, &gpt6cfg1); -    gptStartContinuous(&GPTD6, 2U); -    palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); -} - -void channel_1_stop(void) { -    gptStopTimer(&GPTD6); -    palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL); -    palSetPad(GPIOA, 4); -} - -static float channel_1_frequency = 0.0f; -void         channel_1_set_frequency(float freq) { -    channel_1_frequency = freq; - -    channel_1_stop(); -    if (freq <= 0.0)  // a pause/rest has freq=0 -        return; - -    gpt6cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE; -    channel_1_start(); -} -float channel_1_get_frequency(void) { return channel_1_frequency; } - -void channel_2_start(void) { -    gptStart(&GPTD7, &gpt7cfg1); -    gptStartContinuous(&GPTD7, 2U); -    palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); -} - -void channel_2_stop(void) { -    gptStopTimer(&GPTD7); -    palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL); -    palSetPad(GPIOA, 5); -} - -static float channel_2_frequency = 0.0f; -void         channel_2_set_frequency(float freq) { -    channel_2_frequency = freq; - -    channel_2_stop(); -    if (freq <= 0.0)  // a pause/rest has freq=0 -        return; - -    gpt7cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE; -    channel_2_start(); -} -float channel_2_get_frequency(void) { return channel_2_frequency; } - -static void gpt_audio_state_cb(GPTDriver *gptp) { -    if (audio_update_state()) { -#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) -        // one piezo/speaker connected to both audio pins, the generated square-waves are inverted -        channel_1_set_frequency(audio_get_processed_frequency(0)); -        channel_2_set_frequency(audio_get_processed_frequency(0)); - -#else  // two separate audio outputs/speakers -       // primary speaker on A4, optional secondary on A5 -        if (AUDIO_PIN == A4) { -            channel_1_set_frequency(audio_get_processed_frequency(0)); -            if (AUDIO_PIN_ALT == A5) { -                if (audio_get_number_of_active_tones() > 1) { -                    channel_2_set_frequency(audio_get_processed_frequency(1)); -                } else { -                    channel_2_stop(); -                } -            } -        } - -        // primary speaker on A5, optional secondary on A4 -        if (AUDIO_PIN == A5) { -            channel_2_set_frequency(audio_get_processed_frequency(0)); -            if (AUDIO_PIN_ALT == A4) { -                if (audio_get_number_of_active_tones() > 1) { -                    channel_1_set_frequency(audio_get_processed_frequency(1)); -                } else { -                    channel_1_stop(); -                } -            } -        } -#endif -    } -} - -void audio_driver_initialize() { -    if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { -        palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); -        dacStart(&DACD1, &dac_conf_ch1); - -        // initial setup of the dac-triggering timer is still required, even -        // though it gets reconfigured and restarted later on -        gptStart(&GPTD6, &gpt6cfg1); -    } - -    if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) { -        palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); -        dacStart(&DACD2, &dac_conf_ch2); - -        gptStart(&GPTD7, &gpt7cfg1); -    } - -    /* enable the output buffer, to directly drive external loads with no additional circuitry -     * -     * see: AN4566 Application note: Extending the DAC performance of STM32 microcontrollers -     * Note: Buffer-Off bit -> has to be set 0 to enable the output buffer -     * Note: enabling the output buffer imparts an additional dc-offset of a couple mV -     * -     * this is done here, reaching directly into the stm32 registers since chibios has not implemented BOFF handling yet -     * (see: chibios/os/hal/ports/STM32/todo.txt '- BOFF handling in DACv1.' -     */ -    DACD1.params->dac->CR &= ~DAC_CR_BOFF1; -    DACD2.params->dac->CR &= ~DAC_CR_BOFF2; - -    // start state-updater -    gptStart(&AUDIO_STATE_TIMER, &gptStateUpdateCfg); -} - -void audio_driver_stop(void) { -    if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { -        gptStopTimer(&GPTD6); - -        // stop the ongoing conversion and put the output in a known state -        dacStopConversion(&DACD1); -        dacPutChannelX(&DACD1, 0, AUDIO_DAC_OFF_VALUE); -    } - -    if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) { -        gptStopTimer(&GPTD7); - -        dacStopConversion(&DACD2); -        dacPutChannelX(&DACD2, 0, AUDIO_DAC_OFF_VALUE); -    } -    gptStopTimer(&AUDIO_STATE_TIMER); -} - -void audio_driver_start(void) { -    if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { -        dacStartConversion(&DACD1, &dac_conv_grp_ch1, (dacsample_t *)dac_buffer_1, AUDIO_DAC_BUFFER_SIZE); -    } -    if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) { -        dacStartConversion(&DACD2, &dac_conv_grp_ch2, (dacsample_t *)dac_buffer_2, AUDIO_DAC_BUFFER_SIZE); -    } -    gptStartContinuous(&AUDIO_STATE_TIMER, 2U); -} diff --git a/quantum/audio/driver_chibios_pwm.h b/quantum/audio/driver_chibios_pwm.h deleted file mode 100644 index 86cab916e1..0000000000 --- a/quantum/audio/driver_chibios_pwm.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright 2020 Jack Humbert - * Copyright 2020 JohSchneider - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ -#pragma once - -#if !defined(AUDIO_PWM_DRIVER) -// NOTE: Timer2 seems to be used otherwise in QMK, otherwise we could default to A5 (= TIM2_CH1, with PWMD2 and alternate-function(1)) -#    define AUDIO_PWM_DRIVER PWMD1 -#endif - -#if !defined(AUDIO_PWM_CHANNEL) -// NOTE: sticking to the STM data-sheet numbering: TIMxCH1 to TIMxCH4 -// default: STM32F303CC PA8+TIM1_CH1 -> 1 -#    define AUDIO_PWM_CHANNEL 1 -#endif - -#if !defined(AUDIO_PWM_PAL_MODE) -// pin-alternate function: see the data-sheet for which pin needs what AF to connect to TIMx_CHy -// default: STM32F303CC PA8+TIM1_CH1 -> 6 -#    define AUDIO_PWM_PAL_MODE 6 -#endif - -#if !defined(AUDIO_STATE_TIMER) -// timer used to trigger updates in the audio-system, configured/enabled in chibios mcuconf. -// Tim6 is the default for "larger" STMs, smaller ones might not have this one (enabled) and need to switch to a different one (e.g.: STM32F103 has only Tim1-Tim4) -#    define AUDIO_STATE_TIMER GPTD6 -#endif diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c deleted file mode 100644 index 3c7d89b290..0000000000 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ /dev/null @@ -1,144 +0,0 @@ -/* Copyright 2020 Jack Humbert - * Copyright 2020 JohSchneider - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -/* -Audio Driver: PWM - -the duty-cycle is always kept at 50%, and the pwm-period is adjusted to match the frequency of a note to be played back. - -this driver uses the chibios-PWM system to produce a square-wave on specific output pins that are connected to the PWM hardware. -The hardware directly toggles the pin via its alternate function. see your MCUs data-sheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function. - - */ - -#include "audio.h" -#include "ch.h" -#include "hal.h" - -#if !defined(AUDIO_PIN) -#    error "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM PWM settings" -#endif - -extern bool    playing_note; -extern bool    playing_melody; -extern uint8_t note_timbre; - -static PWMConfig pwmCFG = { -    .frequency = 100000, /* PWM clock frequency  */ -    // CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no output=silence in the meantime -    .period   = 2,    /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ -    .callback = NULL, /* no callback, the hardware directly toggles the pin */ -    .channels = -        { -#if AUDIO_PWM_CHANNEL == 4 -            {PWM_OUTPUT_DISABLED, NULL},   /* channel 0 -> TIMx_CH1 */ -            {PWM_OUTPUT_DISABLED, NULL},   /* channel 1 -> TIMx_CH2 */ -            {PWM_OUTPUT_DISABLED, NULL},   /* channel 2 -> TIMx_CH3 */ -            {PWM_OUTPUT_ACTIVE_HIGH, NULL} /* channel 3 -> TIMx_CH4 */ -#elif AUDIO_PWM_CHANNEL == 3 -            {PWM_OUTPUT_DISABLED, NULL}, -            {PWM_OUTPUT_DISABLED, NULL}, -            {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH3 */ -            {PWM_OUTPUT_DISABLED, NULL} -#elif AUDIO_PWM_CHANNEL == 2 -            {PWM_OUTPUT_DISABLED, NULL}, -            {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH2 */ -            {PWM_OUTPUT_DISABLED, NULL}, -            {PWM_OUTPUT_DISABLED, NULL} -#else /*fallback to CH1 */ -            {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH1 */ -            {PWM_OUTPUT_DISABLED, NULL}, -            {PWM_OUTPUT_DISABLED, NULL}, -            {PWM_OUTPUT_DISABLED, NULL} -#endif -        }, -}; - -static float channel_1_frequency = 0.0f; -void         channel_1_set_frequency(float freq) { -    channel_1_frequency = freq; - -    if (freq <= 0.0)  // a pause/rest has freq=0 -        return; - -    pwmcnt_t period = (pwmCFG.frequency / freq); -    pwmChangePeriod(&AUDIO_PWM_DRIVER, period); -    pwmEnableChannel(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1, -                     // adjust the duty-cycle so that the output is for 'note_timbre' duration HIGH -                     PWM_PERCENTAGE_TO_WIDTH(&AUDIO_PWM_DRIVER, (100 - note_timbre) * 100)); -} - -float channel_1_get_frequency(void) { return channel_1_frequency; } - -void channel_1_start(void) { -    pwmStop(&AUDIO_PWM_DRIVER); -    pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); -} - -void channel_1_stop(void) { pwmStop(&AUDIO_PWM_DRIVER); } - -static void gpt_callback(GPTDriver *gptp); -GPTConfig   gptCFG = { -    /* a whole note is one beat, which is - per definition in musical_notes.h - set to 64 -       the longest note is BREAVE_DOT=128+64=192, the shortest SIXTEENTH=4 -       the tempo (which might vary!) is in bpm (beats per minute) -       therefore: if the timer ticks away at .frequency = (60*64)Hz, -       and the .interval counts from 64 downwards - audio_update_state is -       called just often enough to not miss any notes -    */ -    .frequency = 60 * 64, -    .callback  = gpt_callback, -}; - -void audio_driver_initialize(void) { -    pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); - -    // connect the AUDIO_PIN to the PWM hardware -#if defined(USE_GPIOV1)  // STM32F103C8 -    palSetLineMode(AUDIO_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL); -#else  // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) -    palSetLineMode(AUDIO_PIN, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(AUDIO_PWM_PAL_MODE)); -#endif - -    gptStart(&AUDIO_STATE_TIMER, &gptCFG); -} - -void audio_driver_start(void) { -    channel_1_stop(); -    channel_1_start(); - -    if (playing_note || playing_melody) { -        gptStartContinuous(&AUDIO_STATE_TIMER, 64); -    } -} - -void audio_driver_stop(void) { -    channel_1_stop(); -    gptStopTimer(&AUDIO_STATE_TIMER); -} - -/* a regular timer task, that checks the note to be currently played - * and updates the pwm to output that frequency - */ -static void gpt_callback(GPTDriver *gptp) { -    float freq;  // TODO: freq_alt - -    if (audio_update_state()) { -        freq = audio_get_processed_frequency(0);  // freq_alt would be index=1 -        channel_1_set_frequency(freq); -    } -} diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c deleted file mode 100644 index 15c3e98b6a..0000000000 --- a/quantum/audio/driver_chibios_pwm_software.c +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright 2020 Jack Humbert - * Copyright 2020 JohSchneider - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -/* -Audio Driver: PWM - -the duty-cycle is always kept at 50%, and the pwm-period is adjusted to match the frequency of a note to be played back. - -this driver uses the chibios-PWM system to produce a square-wave on any given output pin in software -- a pwm callback is used to set/clear the configured pin. - - */ -#include "audio.h" -#include "ch.h" -#include "hal.h" - -#if !defined(AUDIO_PIN) -#    error "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM PWM settings" -#endif -extern bool    playing_note; -extern bool    playing_melody; -extern uint8_t note_timbre; - -static void pwm_audio_period_callback(PWMDriver *pwmp); -static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); - -static PWMConfig pwmCFG = { -    .frequency = 100000, /* PWM clock frequency  */ -    // CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no output=silence in the meantime -    .period   = 2, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ -    .callback = pwm_audio_period_callback, -    .channels = -        { -            // software-PWM just needs another callback on any channel -            {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIMx_CH1 */ -            {PWM_OUTPUT_DISABLED, NULL},                                    /* channel 1 -> TIMx_CH2 */ -            {PWM_OUTPUT_DISABLED, NULL},                                    /* channel 2 -> TIMx_CH3 */ -            {PWM_OUTPUT_DISABLED, NULL}                                     /* channel 3 -> TIMx_CH4 */ -        }, -}; - -static float channel_1_frequency = 0.0f; -void         channel_1_set_frequency(float freq) { -    channel_1_frequency = freq; - -    if (freq <= 0.0)  // a pause/rest has freq=0 -        return; - -    pwmcnt_t period = (pwmCFG.frequency / freq); -    pwmChangePeriod(&AUDIO_PWM_DRIVER, period); - -    pwmEnableChannel(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1, -                     // adjust the duty-cycle so that the output is for 'note_timbre' duration HIGH -                     PWM_PERCENTAGE_TO_WIDTH(&AUDIO_PWM_DRIVER, (100 - note_timbre) * 100)); -} - -float channel_1_get_frequency(void) { return channel_1_frequency; } - -void channel_1_start(void) { -    pwmStop(&AUDIO_PWM_DRIVER); -    pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); - -    pwmEnablePeriodicNotification(&AUDIO_PWM_DRIVER); -    pwmEnableChannelNotification(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1); -} - -void channel_1_stop(void) { -    pwmStop(&AUDIO_PWM_DRIVER); - -    palClearLine(AUDIO_PIN);  // leave the line low, after last note was played - -#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) -    palClearLine(AUDIO_PIN_ALT);  // leave the line low, after last note was played -#endif -} - -// generate a PWM signal on any pin, not necessarily the one connected to the timer -static void pwm_audio_period_callback(PWMDriver *pwmp) { -    (void)pwmp; -    palClearLine(AUDIO_PIN); - -#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) -    palSetLine(AUDIO_PIN_ALT); -#endif -} -static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { -    (void)pwmp; -    if (channel_1_frequency > 0) { -        palSetLine(AUDIO_PIN);  // generate a PWM signal on any pin, not necessarily the one connected to the timer -#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) -        palClearLine(AUDIO_PIN_ALT); -#endif -    } -} - -static void gpt_callback(GPTDriver *gptp); -GPTConfig   gptCFG = { -    /* a whole note is one beat, which is - per definition in musical_notes.h - set to 64 -       the longest note is BREAVE_DOT=128+64=192, the shortest SIXTEENTH=4 -       the tempo (which might vary!) is in bpm (beats per minute) -       therefore: if the timer ticks away at .frequency = (60*64)Hz, -       and the .interval counts from 64 downwards - audio_update_state is -       called just often enough to not miss anything -    */ -    .frequency = 60 * 64, -    .callback  = gpt_callback, -}; - -void audio_driver_initialize(void) { -    pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); - -    palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); -    palClearLine(AUDIO_PIN); - -#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) -    palSetLineMode(AUDIO_PIN_ALT, PAL_MODE_OUTPUT_PUSHPULL); -    palClearLine(AUDIO_PIN_ALT); -#endif - -    pwmEnablePeriodicNotification(&AUDIO_PWM_DRIVER);  // enable pwm callbacks -    pwmEnableChannelNotification(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1); - -    gptStart(&AUDIO_STATE_TIMER, &gptCFG); -} - -void audio_driver_start(void) { -    channel_1_stop(); -    channel_1_start(); - -    if (playing_note || playing_melody) { -        gptStartContinuous(&AUDIO_STATE_TIMER, 64); -    } -} - -void audio_driver_stop(void) { -    channel_1_stop(); -    gptStopTimer(&AUDIO_STATE_TIMER); -} - -/* a regular timer task, that checks the note to be currently played - * and updates the pwm to output that frequency - */ -static void gpt_callback(GPTDriver *gptp) { -    float freq;  // TODO: freq_alt - -    if (audio_update_state()) { -        freq = audio_get_processed_frequency(0);  // freq_alt would be index=1 -        channel_1_set_frequency(freq); -    } -} diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h index b54b397e1c..8e80a016aa 100644 --- a/quantum/audio/song_list.h +++ b/quantum/audio/song_list.h @@ -20,11 +20,9 @@  #include "musical_notes.h" -#if __GNUC__ > 5  // don't use for older gcc compilers since check isn't supported. -#    if __has_include("user_song_list.h") -#        include "user_song_list.h" -#    endif  // if file exists -#endif      // __GNUC__ +#if __has_include("user_song_list.h") +#    include "user_song_list.h" +#endif  // if file exists  #define NO_SOUND diff --git a/quantum/backlight/backlight_chibios.c b/quantum/backlight/backlight_chibios.c index 4d5a69e14e..7c6edd10d6 100644 --- a/quantum/backlight/backlight_chibios.c +++ b/quantum/backlight/backlight_chibios.c @@ -8,9 +8,13 @@  #    define BACKLIGHT_LIMIT_VAL 255  #endif -// GPIOV2 && GPIOV3  #ifndef BACKLIGHT_PAL_MODE -#    define BACKLIGHT_PAL_MODE 2 +#    if defined(USE_GPIOV1) +#        define BACKLIGHT_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL +#    else +// GPIOV2 && GPIOV3 +#        define BACKLIGHT_PAL_MODE 5 +#    endif  #endif  // GENERIC @@ -70,7 +74,7 @@ static uint32_t rescale_limit_val(uint32_t val) {  void backlight_init_ports(void) {  #ifdef USE_GPIOV1 -    palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL); +    palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), BACKLIGHT_PAL_MODE);  #else      palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), PAL_MODE_ALTERNATE(BACKLIGHT_PAL_MODE));  #endif diff --git a/quantum/config_common.h b/quantum/config_common.h index 661609ef2a..d93477b27e 100644 --- a/quantum/config_common.h +++ b/quantum/config_common.h @@ -24,7 +24,4 @@  #define COL2ROW 0  #define ROW2COL 1 -// Deprecated alias - avoid using -#define KEYMAP LAYOUT -  #include "song_list.h" diff --git a/quantum/debounce/asym_eager_defer_pk.c b/quantum/debounce/asym_eager_defer_pk.c index 24380dc5e5..81f39383c4 100644 --- a/quantum/debounce/asym_eager_defer_pk.c +++ b/quantum/debounce/asym_eager_defer_pk.c @@ -46,17 +46,17 @@ When no state changes have occured for DEBOUNCE milliseconds, we push the state.  #define ROW_SHIFTER ((matrix_row_t)1)  typedef struct { -    bool pressed : 1; +    bool    pressed : 1;      uint8_t time : 7;  } debounce_counter_t;  #if DEBOUNCE > 0  static debounce_counter_t *debounce_counters; -static fast_timer_t last_time; -static bool counters_need_update; -static bool matrix_need_update; +static fast_timer_t        last_time; +static bool                counters_need_update; +static bool                matrix_need_update; -#define DEBOUNCE_ELAPSED 0 +#    define DEBOUNCE_ELAPSED 0  static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time);  static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows); @@ -64,7 +64,7 @@ static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], ui  // we use num_rows rather than MATRIX_ROWS to support split keyboards  void debounce_init(uint8_t num_rows) {      debounce_counters = malloc(num_rows * MATRIX_COLS * sizeof(debounce_counter_t)); -    int i = 0; +    int i             = 0;      for (uint8_t r = 0; r < num_rows; r++) {          for (uint8_t c = 0; c < MATRIX_COLS; c++) {              debounce_counters[i++].time = DEBOUNCE_ELAPSED; @@ -81,10 +81,10 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool      bool updated_last = false;      if (counters_need_update) { -        fast_timer_t now = timer_read_fast(); +        fast_timer_t now          = timer_read_fast();          fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time); -        last_time = now; +        last_time    = now;          updated_last = true;          if (elapsed_time > UINT8_MAX) {              elapsed_time = UINT8_MAX; @@ -108,7 +108,7 @@ static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[],      debounce_counter_t *debounce_pointer = debounce_counters;      counters_need_update = false; -    matrix_need_update = false; +    matrix_need_update   = false;      for (uint8_t row = 0; row < num_rows; row++) {          for (uint8_t col = 0; col < MATRIX_COLS; col++) { @@ -146,8 +146,8 @@ static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], ui              if (delta & col_mask) {                  if (debounce_pointer->time == DEBOUNCE_ELAPSED) {                      debounce_pointer->pressed = (raw[row] & col_mask); -                    debounce_pointer->time = DEBOUNCE; -                    counters_need_update = true; +                    debounce_pointer->time    = DEBOUNCE; +                    counters_need_update      = true;                      if (debounce_pointer->pressed) {                          // key-down: eager diff --git a/quantum/debounce/sym_defer_g.c b/quantum/debounce/sym_defer_g.c index fbefd55ede..9155eb914c 100644 --- a/quantum/debounce/sym_defer_g.c +++ b/quantum/debounce/sym_defer_g.c @@ -25,7 +25,7 @@ When no state changes have occured for DEBOUNCE milliseconds, we push the state.  #endif  #if DEBOUNCE > 0 -static bool debouncing = false; +static bool         debouncing = false;  static fast_timer_t debouncing_time;  void debounce_init(uint8_t num_rows) {} diff --git a/quantum/debounce/sym_defer_pk.c b/quantum/debounce/sym_defer_pk.c index 626a9be841..1b698ba347 100644 --- a/quantum/debounce/sym_defer_pk.c +++ b/quantum/debounce/sym_defer_pk.c @@ -49,7 +49,7 @@ static debounce_counter_t *debounce_counters;  static fast_timer_t        last_time;  static bool                counters_need_update; -#define DEBOUNCE_ELAPSED 0 +#    define DEBOUNCE_ELAPSED 0  static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time);  static void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows); @@ -74,10 +74,10 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool      bool updated_last = false;      if (counters_need_update) { -        fast_timer_t now = timer_read_fast(); +        fast_timer_t now          = timer_read_fast();          fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time); -        last_time = now; +        last_time    = now;          updated_last = true;          if (elapsed_time > UINT8_MAX) {              elapsed_time = UINT8_MAX; diff --git a/quantum/debounce/sym_eager_pk.c b/quantum/debounce/sym_eager_pk.c index 15a3242e68..9da000ea9a 100644 --- a/quantum/debounce/sym_eager_pk.c +++ b/quantum/debounce/sym_eager_pk.c @@ -50,7 +50,7 @@ static fast_timer_t        last_time;  static bool                counters_need_update;  static bool                matrix_need_update; -#define DEBOUNCE_ELAPSED 0 +#    define DEBOUNCE_ELAPSED 0  static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time);  static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows); @@ -75,10 +75,10 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool      bool updated_last = false;      if (counters_need_update) { -        fast_timer_t now = timer_read_fast(); +        fast_timer_t now          = timer_read_fast();          fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time); -        last_time = now; +        last_time    = now;          updated_last = true;          if (elapsed_time > UINT8_MAX) {              elapsed_time = UINT8_MAX; @@ -107,7 +107,7 @@ static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time) {          for (uint8_t col = 0; col < MATRIX_COLS; col++) {              if (*debounce_pointer != DEBOUNCE_ELAPSED) {                  if (*debounce_pointer <= elapsed_time) { -                    *debounce_pointer = DEBOUNCE_ELAPSED; +                    *debounce_pointer  = DEBOUNCE_ELAPSED;                      matrix_need_update = true;                  } else {                      *debounce_pointer -= elapsed_time; diff --git a/quantum/debounce/sym_eager_pr.c b/quantum/debounce/sym_eager_pr.c index 2ad592c5a6..eda92a263b 100644 --- a/quantum/debounce/sym_eager_pr.c +++ b/quantum/debounce/sym_eager_pr.c @@ -49,7 +49,7 @@ static debounce_counter_t *debounce_counters;  static fast_timer_t        last_time;  static bool                counters_need_update; -#define DEBOUNCE_ELAPSED 0 +#    define DEBOUNCE_ELAPSED 0  static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time);  static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows); @@ -71,10 +71,10 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool      bool updated_last = false;      if (counters_need_update) { -        fast_timer_t now = timer_read_fast(); +        fast_timer_t now          = timer_read_fast();          fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time); -        last_time = now; +        last_time    = now;          updated_last = true;          if (elapsed_time > UINT8_MAX) {              elapsed_time = UINT8_MAX; @@ -102,7 +102,7 @@ static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time) {      for (uint8_t row = 0; row < num_rows; row++) {          if (*debounce_pointer != DEBOUNCE_ELAPSED) {              if (*debounce_pointer <= elapsed_time) { -                *debounce_pointer = DEBOUNCE_ELAPSED; +                *debounce_pointer  = DEBOUNCE_ELAPSED;                  matrix_need_update = true;              } else {                  *debounce_pointer -= elapsed_time; diff --git a/quantum/debounce/tests/asym_eager_defer_pk_tests.cpp b/quantum/debounce/tests/asym_eager_defer_pk_tests.cpp index fe374c3dfa..44b4fe1956 100644 --- a/quantum/debounce/tests/asym_eager_defer_pk_tests.cpp +++ b/quantum/debounce/tests/asym_eager_defer_pk_tests.cpp @@ -19,7 +19,8 @@  #include "debounce_test_common.h"  TEST_F(DebounceTest, OneKeyShort1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Release key after 1ms delay */          {1, {{0, 1, UP}}, {}}, @@ -43,7 +44,8 @@ TEST_F(DebounceTest, OneKeyShort1) {  }  TEST_F(DebounceTest, OneKeyShort2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Release key after 2ms delay */          {2, {{0, 1, UP}}, {}}, @@ -58,7 +60,8 @@ TEST_F(DebounceTest, OneKeyShort2) {  }  TEST_F(DebounceTest, OneKeyShort3) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Release key after 3ms delay */          {3, {{0, 1, UP}}, {}}, @@ -73,7 +76,8 @@ TEST_F(DebounceTest, OneKeyShort3) {  }  TEST_F(DebounceTest, OneKeyShort4) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Release key after 4ms delay */          {4, {{0, 1, UP}}, {}}, @@ -88,7 +92,8 @@ TEST_F(DebounceTest, OneKeyShort4) {  }  TEST_F(DebounceTest, OneKeyShort5) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Release key after 5ms delay */ @@ -102,7 +107,8 @@ TEST_F(DebounceTest, OneKeyShort5) {  }  TEST_F(DebounceTest, OneKeyShort6) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Release key after 6ms delay */ @@ -116,7 +122,8 @@ TEST_F(DebounceTest, OneKeyShort6) {  }  TEST_F(DebounceTest, OneKeyShort7) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Release key after 7ms delay */ @@ -130,7 +137,8 @@ TEST_F(DebounceTest, OneKeyShort7) {  }  TEST_F(DebounceTest, OneKeyShort8) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Release key after 1ms delay */          {1, {{0, 1, UP}}, {}}, @@ -145,7 +153,8 @@ TEST_F(DebounceTest, OneKeyShort8) {  }  TEST_F(DebounceTest, OneKeyShort9) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Release key after 1ms delay */          {1, {{0, 1, UP}}, {}}, @@ -159,7 +168,8 @@ TEST_F(DebounceTest, OneKeyShort9) {  }  TEST_F(DebounceTest, OneKeyBouncing1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}},          {2, {{0, 1, DOWN}}, {}}, @@ -185,7 +195,8 @@ TEST_F(DebounceTest, OneKeyBouncing1) {  }  TEST_F(DebounceTest, OneKeyBouncing2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Change twice in the same time period */          {1, {{0, 1, UP}}, {}}, @@ -217,7 +228,8 @@ TEST_F(DebounceTest, OneKeyBouncing2) {  }  TEST_F(DebounceTest, OneKeyLong) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {25, {{0, 1, UP}}, {}}, @@ -236,7 +248,8 @@ TEST_F(DebounceTest, OneKeyLong) {  }  TEST_F(DebounceTest, TwoKeysShort) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 2, DOWN}}, {{0, 2, DOWN}}},          /* Release key after 2ms delay */ @@ -249,14 +262,14 @@ TEST_F(DebounceTest, TwoKeysShort) {          {10, {}, {{0, 1, UP}}}, /* 5ms+5ms after DOWN at time 0 */          /* Press key again after 1ms delay */          {11, {{0, 1, DOWN}}, {{0, 1, DOWN}, {0, 2, UP}}}, /* 5ms+5ms after DOWN at time 0 */ -        {12, {{0, 2, DOWN}}, {{0, 2, DOWN}}}, /* 5ms+5ms after DOWN at time 0 */ +        {12, {{0, 2, DOWN}}, {{0, 2, DOWN}}},             /* 5ms+5ms after DOWN at time 0 */      });      runEvents();  } -  TEST_F(DebounceTest, OneKeyDelayedScan1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late, immediately release key */ @@ -269,7 +282,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan1) {  }  TEST_F(DebounceTest, OneKeyDelayedScan2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late, immediately release key */ @@ -283,7 +297,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan2) {  }  TEST_F(DebounceTest, OneKeyDelayedScan3) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late */ @@ -298,7 +313,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan3) {  }  TEST_F(DebounceTest, OneKeyDelayedScan4) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late */ @@ -314,7 +330,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan4) {  }  TEST_F(DebounceTest, OneKeyDelayedScan5) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {5, {{0, 1, UP}}, {}}, @@ -329,7 +346,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan5) {  }  TEST_F(DebounceTest, OneKeyDelayedScan6) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {5, {{0, 1, UP}}, {}}, @@ -345,7 +363,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan6) {  }  TEST_F(DebounceTest, OneKeyDelayedScan7) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {5, {{0, 1, UP}}, {}}, @@ -358,7 +377,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan7) {  }  TEST_F(DebounceTest, OneKeyDelayedScan8) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is a bit late */ diff --git a/quantum/debounce/tests/debounce_test_common.cpp b/quantum/debounce/tests/debounce_test_common.cpp index 1c5e7c9f4e..f9414e571d 100644 --- a/quantum/debounce/tests/debounce_test_common.cpp +++ b/quantum/debounce/tests/debounce_test_common.cpp @@ -31,9 +31,7 @@ void set_time(uint32_t t);  void advance_time(uint32_t ms);  } -void DebounceTest::addEvents(std::initializer_list<DebounceTestEvent> events) { -    events_.insert(events_.end(), events.begin(), events.end()); -} +void DebounceTest::addEvents(std::initializer_list<DebounceTestEvent> events) { events_.insert(events_.end(), events.begin(), events.end()); }  void DebounceTest::runEvents() {      /* Run the test multiple times, from 1kHz to 10kHz scan rate */ @@ -54,7 +52,7 @@ void DebounceTest::runEvents() {  void DebounceTest::runEventsInternal() {      fast_timer_t previous = 0; -    bool first = true; +    bool         first    = true;      /* Initialise keyboard with start time (offset to avoid testing at 0) and all keys UP */      debounce_init(MATRIX_ROWS); @@ -80,7 +78,7 @@ void DebounceTest::runEventsInternal() {              }          } -        first = false; +        first    = false;          previous = event.time_;          /* Prepare input matrix */ @@ -98,12 +96,7 @@ void DebounceTest::runEventsInternal() {          /* Check output matrix has expected change events */          for (auto &output : event.outputs_) { -            EXPECT_EQ(!!(cooked_matrix_[output.row_] & (1U << output.col_)), directionValue(output.direction_)) -                    << "Missing event at " << strTime() -                    << " expected key " << output.row_ << "," << output.col_ << " " << directionLabel(output.direction_) -                    << "\ninput_matrix: changed=" << !event.inputs_.empty() << "\n" << strMatrix(input_matrix_) -                    << "\nexpected_matrix:\n" << strMatrix(output_matrix_) -                    << "\nactual_matrix:\n" << strMatrix(cooked_matrix_); +            EXPECT_EQ(!!(cooked_matrix_[output.row_] & (1U << output.col_)), directionValue(output.direction_)) << "Missing event at " << strTime() << " expected key " << output.row_ << "," << output.col_ << " " << directionLabel(output.direction_) << "\ninput_matrix: changed=" << !event.inputs_.empty() << "\n" << strMatrix(input_matrix_) << "\nexpected_matrix:\n" << strMatrix(output_matrix_) << "\nactual_matrix:\n" << strMatrix(cooked_matrix_);          }          /* Check output matrix has no other changes */ @@ -133,27 +126,20 @@ void DebounceTest::runDebounce(bool changed) {      debounce(raw_matrix_, cooked_matrix_, MATRIX_ROWS, changed);      if (!std::equal(std::begin(input_matrix_), std::end(input_matrix_), std::begin(raw_matrix_))) { -        FAIL() << "Fatal error: debounce() modified raw matrix at " << strTime() -            << "\ninput_matrix: changed=" << changed << "\n" << strMatrix(input_matrix_) -            << "\nraw_matrix:\n" << strMatrix(raw_matrix_); +        FAIL() << "Fatal error: debounce() modified raw matrix at " << strTime() << "\ninput_matrix: changed=" << changed << "\n" << strMatrix(input_matrix_) << "\nraw_matrix:\n" << strMatrix(raw_matrix_);      }  }  void DebounceTest::checkCookedMatrix(bool changed, const std::string &error_message) {      if (!std::equal(std::begin(output_matrix_), std::end(output_matrix_), std::begin(cooked_matrix_))) { -        FAIL() << "Unexpected event: " << error_message << " at " << strTime() -            << "\ninput_matrix: changed=" << changed << "\n" << strMatrix(input_matrix_) -            << "\nexpected_matrix:\n" << strMatrix(output_matrix_) -            << "\nactual_matrix:\n" << strMatrix(cooked_matrix_); +        FAIL() << "Unexpected event: " << error_message << " at " << strTime() << "\ninput_matrix: changed=" << changed << "\n" << strMatrix(input_matrix_) << "\nexpected_matrix:\n" << strMatrix(output_matrix_) << "\nactual_matrix:\n" << strMatrix(cooked_matrix_);      }  }  std::string DebounceTest::strTime() {      std::stringstream text; -    text << "time " << (timer_read_fast() - time_offset_) -        << " (extra_iterations=" << extra_iterations_ -        << ", auto_advance_time=" << auto_advance_time_ << ")"; +    text << "time " << (timer_read_fast() - time_offset_) << " (extra_iterations=" << extra_iterations_ << ", auto_advance_time=" << auto_advance_time_ << ")";      return text.str();  } @@ -181,49 +167,39 @@ std::string DebounceTest::strMatrix(matrix_row_t matrix[]) {  bool DebounceTest::directionValue(Direction direction) {      switch (direction) { -    case DOWN: -        return true; +        case DOWN: +            return true; -    case UP: -        return false; +        case UP: +            return false;      }  }  std::string DebounceTest::directionLabel(Direction direction) {      switch (direction) { -    case DOWN: -        return "DOWN"; +        case DOWN: +            return "DOWN"; -    case UP: -        return "UP"; +        case UP: +            return "UP";      }  }  /* Modify a matrix and verify that events always specify a change */  void DebounceTest::matrixUpdate(matrix_row_t matrix[], const std::string &name, const MatrixTestEvent &event) { -    ASSERT_NE(!!(matrix[event.row_] & (1U << event.col_)), directionValue(event.direction_)) -        << "Test " << name << " at " << strTime() -        << " sets key " << event.row_ << "," << event.col_ << " " << directionLabel(event.direction_) -        << " but it is already " << directionLabel(event.direction_) -        << "\n" << name << "_matrix:\n" << strMatrix(matrix); +    ASSERT_NE(!!(matrix[event.row_] & (1U << event.col_)), directionValue(event.direction_)) << "Test " << name << " at " << strTime() << " sets key " << event.row_ << "," << event.col_ << " " << directionLabel(event.direction_) << " but it is already " << directionLabel(event.direction_) << "\n" << name << "_matrix:\n" << strMatrix(matrix);      switch (event.direction_) { -    case DOWN: -        matrix[event.row_] |= (1U << event.col_); -        break; +        case DOWN: +            matrix[event.row_] |= (1U << event.col_); +            break; -    case UP: -        matrix[event.row_] &= ~(1U << event.col_); -        break; +        case UP: +            matrix[event.row_] &= ~(1U << event.col_); +            break;      }  } -DebounceTestEvent::DebounceTestEvent(fast_timer_t time, -        std::initializer_list<MatrixTestEvent> inputs, -        std::initializer_list<MatrixTestEvent> outputs) -        : time_(time), inputs_(inputs), outputs_(outputs) { -} +DebounceTestEvent::DebounceTestEvent(fast_timer_t time, std::initializer_list<MatrixTestEvent> inputs, std::initializer_list<MatrixTestEvent> outputs) : time_(time), inputs_(inputs), outputs_(outputs) {} -MatrixTestEvent::MatrixTestEvent(int row, int col, Direction direction) -        : row_(row), col_(col), direction_(direction) { -} +MatrixTestEvent::MatrixTestEvent(int row, int col, Direction direction) : row_(row), col_(col), direction_(direction) {} diff --git a/quantum/debounce/tests/debounce_test_common.h b/quantum/debounce/tests/debounce_test_common.h index d87e310594..b7becb3782 100644 --- a/quantum/debounce/tests/debounce_test_common.h +++ b/quantum/debounce/tests/debounce_test_common.h @@ -31,36 +31,34 @@ enum Direction {  };  class MatrixTestEvent { -public: +   public:      MatrixTestEvent(int row, int col, Direction direction); -    const int row_; -    const int col_; +    const int       row_; +    const int       col_;      const Direction direction_;  };  class DebounceTestEvent { -public: +   public:      // 0, {{0, 1, DOWN}}, {{0, 1, DOWN}}) -    DebounceTestEvent(fast_timer_t time, -        std::initializer_list<MatrixTestEvent> inputs, -        std::initializer_list<MatrixTestEvent> outputs); +    DebounceTestEvent(fast_timer_t time, std::initializer_list<MatrixTestEvent> inputs, std::initializer_list<MatrixTestEvent> outputs); -    const fast_timer_t time_; +    const fast_timer_t               time_;      const std::list<MatrixTestEvent> inputs_;      const std::list<MatrixTestEvent> outputs_;  };  class DebounceTest : public ::testing::Test { -protected: +   protected:      void addEvents(std::initializer_list<DebounceTestEvent> events);      void runEvents();      fast_timer_t time_offset_ = 7777; -    bool time_jumps_ = false; +    bool         time_jumps_  = false; -private: -    static bool directionValue(Direction direction); +   private: +    static bool        directionValue(Direction direction);      static std::string directionLabel(Direction direction);      void runEventsInternal(); @@ -78,6 +76,6 @@ private:      matrix_row_t cooked_matrix_[MATRIX_ROWS];      matrix_row_t output_matrix_[MATRIX_ROWS]; -    int extra_iterations_; +    int  extra_iterations_;      bool auto_advance_time_;  }; diff --git a/quantum/debounce/tests/sym_defer_g_tests.cpp b/quantum/debounce/tests/sym_defer_g_tests.cpp index a56aecd8f3..73d3d45e30 100644 --- a/quantum/debounce/tests/sym_defer_g_tests.cpp +++ b/quantum/debounce/tests/sym_defer_g_tests.cpp @@ -19,7 +19,8 @@  #include "debounce_test_common.h"  TEST_F(DebounceTest, OneKeyShort1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}}}, @@ -32,7 +33,8 @@ TEST_F(DebounceTest, OneKeyShort1) {  }  TEST_F(DebounceTest, OneKeyShort2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}}}, @@ -45,7 +47,8 @@ TEST_F(DebounceTest, OneKeyShort2) {  }  TEST_F(DebounceTest, OneKeyShort3) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}}}, @@ -58,7 +61,8 @@ TEST_F(DebounceTest, OneKeyShort3) {  }  TEST_F(DebounceTest, OneKeyTooQuick1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          /* Release key exactly on the debounce time */          {5, {{0, 1, UP}}, {}}, @@ -67,7 +71,8 @@ TEST_F(DebounceTest, OneKeyTooQuick1) {  }  TEST_F(DebounceTest, OneKeyTooQuick2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}}}, @@ -80,7 +85,8 @@ TEST_F(DebounceTest, OneKeyTooQuick2) {  }  TEST_F(DebounceTest, OneKeyBouncing1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {1, {{0, 1, UP}}, {}},          {2, {{0, 1, DOWN}}, {}}, @@ -94,7 +100,8 @@ TEST_F(DebounceTest, OneKeyBouncing1) {  }  TEST_F(DebounceTest, OneKeyBouncing2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}}},          {6, {{0, 1, UP}}, {}}, @@ -108,7 +115,8 @@ TEST_F(DebounceTest, OneKeyBouncing2) {  }  TEST_F(DebounceTest, OneKeyLong) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}}}, @@ -125,7 +133,8 @@ TEST_F(DebounceTest, OneKeyLong) {  }  TEST_F(DebounceTest, TwoKeysShort) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {1, {{0, 2, DOWN}}, {}}, @@ -140,7 +149,8 @@ TEST_F(DebounceTest, TwoKeysShort) {  }  TEST_F(DebounceTest, TwoKeysSimultaneous1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, @@ -152,7 +162,8 @@ TEST_F(DebounceTest, TwoKeysSimultaneous1) {  }  TEST_F(DebounceTest, TwoKeysSimultaneous2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {1, {{0, 2, DOWN}}, {}}, @@ -167,7 +178,8 @@ TEST_F(DebounceTest, TwoKeysSimultaneous2) {  }  TEST_F(DebounceTest, OneKeyDelayedScan1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          /* Processing is very late */ @@ -182,7 +194,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan1) {  }  TEST_F(DebounceTest, OneKeyDelayedScan2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          /* Processing is very late */ @@ -197,7 +210,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan2) {  }  TEST_F(DebounceTest, OneKeyDelayedScan3) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          /* Release key before debounce expires */ @@ -208,7 +222,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan3) {  }  TEST_F(DebounceTest, OneKeyDelayedScan4) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          /* Processing is a bit late */ diff --git a/quantum/debounce/tests/sym_defer_pk_tests.cpp b/quantum/debounce/tests/sym_defer_pk_tests.cpp index 1f3061e59c..7542c2dad4 100644 --- a/quantum/debounce/tests/sym_defer_pk_tests.cpp +++ b/quantum/debounce/tests/sym_defer_pk_tests.cpp @@ -19,7 +19,8 @@  #include "debounce_test_common.h"  TEST_F(DebounceTest, OneKeyShort1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}}}, @@ -32,7 +33,8 @@ TEST_F(DebounceTest, OneKeyShort1) {  }  TEST_F(DebounceTest, OneKeyShort2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}}}, @@ -45,7 +47,8 @@ TEST_F(DebounceTest, OneKeyShort2) {  }  TEST_F(DebounceTest, OneKeyShort3) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}}}, @@ -58,7 +61,8 @@ TEST_F(DebounceTest, OneKeyShort3) {  }  TEST_F(DebounceTest, OneKeyTooQuick1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          /* Release key exactly on the debounce time */          {5, {{0, 1, UP}}, {}}, @@ -67,7 +71,8 @@ TEST_F(DebounceTest, OneKeyTooQuick1) {  }  TEST_F(DebounceTest, OneKeyTooQuick2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}}}, @@ -80,7 +85,8 @@ TEST_F(DebounceTest, OneKeyTooQuick2) {  }  TEST_F(DebounceTest, OneKeyBouncing1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {1, {{0, 1, UP}}, {}},          {2, {{0, 1, DOWN}}, {}}, @@ -94,7 +100,8 @@ TEST_F(DebounceTest, OneKeyBouncing1) {  }  TEST_F(DebounceTest, OneKeyBouncing2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}}},          {6, {{0, 1, UP}}, {}}, @@ -108,7 +115,8 @@ TEST_F(DebounceTest, OneKeyBouncing2) {  }  TEST_F(DebounceTest, OneKeyLong) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}}}, @@ -125,7 +133,8 @@ TEST_F(DebounceTest, OneKeyLong) {  }  TEST_F(DebounceTest, TwoKeysShort) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {1, {{0, 2, DOWN}}, {}}, @@ -142,7 +151,8 @@ TEST_F(DebounceTest, TwoKeysShort) {  }  TEST_F(DebounceTest, TwoKeysSimultaneous1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {}},          {5, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, @@ -154,7 +164,8 @@ TEST_F(DebounceTest, TwoKeysSimultaneous1) {  }  TEST_F(DebounceTest, TwoKeysSimultaneous2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          {1, {{0, 2, DOWN}}, {}}, @@ -169,7 +180,8 @@ TEST_F(DebounceTest, TwoKeysSimultaneous2) {  }  TEST_F(DebounceTest, OneKeyDelayedScan1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          /* Processing is very late */ @@ -184,7 +196,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan1) {  }  TEST_F(DebounceTest, OneKeyDelayedScan2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          /* Processing is very late */ @@ -199,7 +212,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan2) {  }  TEST_F(DebounceTest, OneKeyDelayedScan3) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          /* Release key before debounce expires */ @@ -210,7 +224,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan3) {  }  TEST_F(DebounceTest, OneKeyDelayedScan4) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {}},          /* Processing is a bit late */ diff --git a/quantum/debounce/tests/sym_eager_pk_tests.cpp b/quantum/debounce/tests/sym_eager_pk_tests.cpp index e0fc205e33..d9a02fe33c 100644 --- a/quantum/debounce/tests/sym_eager_pk_tests.cpp +++ b/quantum/debounce/tests/sym_eager_pk_tests.cpp @@ -19,7 +19,8 @@  #include "debounce_test_common.h"  TEST_F(DebounceTest, OneKeyShort1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}}, @@ -32,7 +33,8 @@ TEST_F(DebounceTest, OneKeyShort1) {  }  TEST_F(DebounceTest, OneKeyShort2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}}, @@ -45,7 +47,8 @@ TEST_F(DebounceTest, OneKeyShort2) {  }  TEST_F(DebounceTest, OneKeyShort3) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}}, @@ -58,7 +61,8 @@ TEST_F(DebounceTest, OneKeyShort3) {  }  TEST_F(DebounceTest, OneKeyShort4) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}}, @@ -71,7 +75,8 @@ TEST_F(DebounceTest, OneKeyShort4) {  }  TEST_F(DebounceTest, OneKeyShort5) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}}, @@ -83,7 +88,8 @@ TEST_F(DebounceTest, OneKeyShort5) {  }  TEST_F(DebounceTest, OneKeyShort6) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}}, @@ -95,7 +101,8 @@ TEST_F(DebounceTest, OneKeyShort6) {  }  TEST_F(DebounceTest, OneKeyBouncing1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}},          {2, {{0, 1, DOWN}}, {}}, @@ -110,7 +117,8 @@ TEST_F(DebounceTest, OneKeyBouncing1) {  }  TEST_F(DebounceTest, OneKeyBouncing2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Change twice in the same time period */          {1, {{0, 1, UP}}, {}}, @@ -135,7 +143,8 @@ TEST_F(DebounceTest, OneKeyBouncing2) {  }  TEST_F(DebounceTest, OneKeyLong) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {25, {{0, 1, UP}}, {{0, 1, UP}}}, @@ -146,7 +155,8 @@ TEST_F(DebounceTest, OneKeyLong) {  }  TEST_F(DebounceTest, TwoKeysShort) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}},          {2, {{0, 2, DOWN}}, {{0, 2, DOWN}}}, @@ -167,7 +177,8 @@ TEST_F(DebounceTest, TwoKeysShort) {  }  TEST_F(DebounceTest, OneKeyDelayedScan1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late but the change will now be accepted */ @@ -178,7 +189,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan1) {  }  TEST_F(DebounceTest, OneKeyDelayedScan2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late but the change will now be accepted even with a 1 scan delay */ @@ -190,7 +202,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan2) {  }  TEST_F(DebounceTest, OneKeyDelayedScan3) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late but the change will now be accepted even with a 1ms delay */ @@ -202,7 +215,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan3) {  }  TEST_F(DebounceTest, OneKeyDelayedScan4) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is a bit late but the change will now be accepted */ @@ -213,7 +227,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan4) {  }  TEST_F(DebounceTest, OneKeyDelayedScan5) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late but the change will now be accepted even with a 1 scan delay */ @@ -225,7 +240,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan5) {  }  TEST_F(DebounceTest, OneKeyDelayedScan6) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late but the change will now be accepted even with a 1ms delay */ diff --git a/quantum/debounce/tests/sym_eager_pr_tests.cpp b/quantum/debounce/tests/sym_eager_pr_tests.cpp index 2c4bca127e..e91dd9cb87 100644 --- a/quantum/debounce/tests/sym_eager_pr_tests.cpp +++ b/quantum/debounce/tests/sym_eager_pr_tests.cpp @@ -19,7 +19,8 @@  #include "debounce_test_common.h"  TEST_F(DebounceTest, OneKeyShort1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}}, @@ -32,7 +33,8 @@ TEST_F(DebounceTest, OneKeyShort1) {  }  TEST_F(DebounceTest, OneKeyShort2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}}, @@ -45,7 +47,8 @@ TEST_F(DebounceTest, OneKeyShort2) {  }  TEST_F(DebounceTest, OneKeyShort3) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}}, @@ -58,7 +61,8 @@ TEST_F(DebounceTest, OneKeyShort3) {  }  TEST_F(DebounceTest, OneKeyShort4) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}}, @@ -71,7 +75,8 @@ TEST_F(DebounceTest, OneKeyShort4) {  }  TEST_F(DebounceTest, OneKeyShort5) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}}, @@ -83,7 +88,8 @@ TEST_F(DebounceTest, OneKeyShort5) {  }  TEST_F(DebounceTest, OneKeyShort6) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}}, @@ -95,7 +101,8 @@ TEST_F(DebounceTest, OneKeyShort6) {  }  TEST_F(DebounceTest, OneKeyBouncing1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}},          {2, {{0, 1, DOWN}}, {}}, @@ -110,7 +117,8 @@ TEST_F(DebounceTest, OneKeyBouncing1) {  }  TEST_F(DebounceTest, OneKeyBouncing2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Change twice in the same time period */          {1, {{0, 1, UP}}, {}}, @@ -135,7 +143,8 @@ TEST_F(DebounceTest, OneKeyBouncing2) {  }  TEST_F(DebounceTest, OneKeyLong) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {25, {{0, 1, UP}}, {{0, 1, UP}}}, @@ -146,7 +155,8 @@ TEST_F(DebounceTest, OneKeyLong) {  }  TEST_F(DebounceTest, TwoRowsShort) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}},          {2, {{2, 0, DOWN}}, {{2, 0, DOWN}}}, @@ -167,7 +177,8 @@ TEST_F(DebounceTest, TwoRowsShort) {  }  TEST_F(DebounceTest, TwoKeysOverlap) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          {1, {{0, 1, UP}}, {}},          /* Press a second key during the first debounce */ @@ -190,7 +201,8 @@ TEST_F(DebounceTest, TwoKeysOverlap) {  }  TEST_F(DebounceTest, TwoKeysSimultaneous1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {{0, 1, DOWN}, {0, 2, DOWN}}},          {20, {{0, 1, UP}}, {{0, 1, UP}}},          {21, {{0, 2, UP}}, {}}, @@ -202,7 +214,8 @@ TEST_F(DebounceTest, TwoKeysSimultaneous1) {  }  TEST_F(DebounceTest, TwoKeysSimultaneous2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {{0, 1, DOWN}, {0, 2, DOWN}}},          {20, {{0, 1, UP}, {0, 2, UP}}, {{0, 1, UP}, {0, 2, UP}}},      }); @@ -210,7 +223,8 @@ TEST_F(DebounceTest, TwoKeysSimultaneous2) {  }  TEST_F(DebounceTest, OneKeyDelayedScan1) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late but the change will now be accepted */ @@ -221,7 +235,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan1) {  }  TEST_F(DebounceTest, OneKeyDelayedScan2) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late but the change will now be accepted even with a 1 scan delay */ @@ -233,7 +248,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan2) {  }  TEST_F(DebounceTest, OneKeyDelayedScan3) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late but the change will now be accepted even with a 1ms delay */ @@ -245,7 +261,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan3) {  }  TEST_F(DebounceTest, OneKeyDelayedScan4) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is a bit late but the change will now be accepted */ @@ -256,7 +273,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan4) {  }  TEST_F(DebounceTest, OneKeyDelayedScan5) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late but the change will now be accepted even with a 1 scan delay */ @@ -268,7 +286,8 @@ TEST_F(DebounceTest, OneKeyDelayedScan5) {  }  TEST_F(DebounceTest, OneKeyDelayedScan6) { -    addEvents({ /* Time, Inputs, Outputs */ +    addEvents({ +        /* Time, Inputs, Outputs */          {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}},          /* Processing is very late but the change will now be accepted even with a 1ms delay */ diff --git a/quantum/eeconfig.c b/quantum/eeconfig.c index 92f0ac4439..4c2ad2490c 100644 --- a/quantum/eeconfig.c +++ b/quantum/eeconfig.c @@ -4,11 +4,6 @@  #include "eeconfig.h"  #include "action_layer.h" -#ifdef STM32_EEPROM_ENABLE -#    include <hal.h> -#    include "eeprom_stm32.h" -#endif -  #if defined(EEPROM_DRIVER)  #    include "eeprom_driver.h"  #endif @@ -43,9 +38,6 @@ __attribute__((weak)) void eeconfig_init_kb(void) {   * FIXME: needs doc   */  void eeconfig_init_quantum(void) { -#ifdef STM32_EEPROM_ENABLE -    EEPROM_Erase(); -#endif  #if defined(EEPROM_DRIVER)      eeprom_driver_erase();  #endif @@ -111,9 +103,6 @@ void eeconfig_enable(void) { eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_N   * FIXME: needs doc   */  void eeconfig_disable(void) { -#ifdef STM32_EEPROM_ENABLE -    EEPROM_Erase(); -#endif  #if defined(EEPROM_DRIVER)      eeprom_driver_erase();  #endif diff --git a/quantum/eeconfig.h b/quantum/eeconfig.h index bd39971b2c..22d874273c 100644 --- a/quantum/eeconfig.h +++ b/quantum/eeconfig.h @@ -111,3 +111,29 @@ void     eeconfig_update_haptic(uint32_t val);  bool eeconfig_read_handedness(void);  void eeconfig_update_handedness(bool val); + +#define EECONFIG_DEBOUNCE_HELPER(name, offset, config)                     \ +    static uint8_t dirty_##name = false;                                   \ +                                                                           \ +    static inline void eeconfig_init_##name(void) {                        \ +        eeprom_read_block(&config, offset, sizeof(config));                \ +        dirty_##name = false;                                              \ +    }                                                                      \ +    static inline void eeconfig_flush_##name(bool force) {                 \ +        if (force || dirty_##name) {                                       \ +            eeprom_update_block(&config, offset, sizeof(config));          \ +            dirty_##name = false;                                          \ +        }                                                                  \ +    }                                                                      \ +    static inline void eeconfig_flush_##name##_task(uint16_t timeout) {    \ +        static uint16_t flush_timer = 0;                                   \ +        if (timer_elapsed(flush_timer) > timeout) {                        \ +            eeconfig_flush_##name(false);                                  \ +            flush_timer = timer_read();                                    \ +        }                                                                  \ +    }                                                                      \ +    static inline void eeconfig_flag_##name(bool v) { dirty_##name |= v; } \ +    static inline void eeconfig_write_##name(typeof(config) conf) {        \ +        memcpy(&config, &conf, sizeof(config));                            \ +        eeconfig_flag_##name(true);                                        \ +    } diff --git a/quantum/haptic.c b/quantum/haptic.c index 65abcc15fa..f915acf946 100644 --- a/quantum/haptic.c +++ b/quantum/haptic.c @@ -17,6 +17,8 @@  #include "haptic.h"  #include "eeconfig.h"  #include "debug.h" +#include "usb_device_state.h" +#include "gpio.h"  #ifdef DRV2605L  #    include "DRV2605L.h"  #endif @@ -26,6 +28,29 @@  haptic_config_t haptic_config; +static void update_haptic_enable_gpios(void) { +    if (haptic_config.enable && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED))) { +#if defined(HAPTIC_ENABLE_PIN) +        HAPTIC_ENABLE_PIN_WRITE_ACTIVE(); +#endif +#if defined(HAPTIC_ENABLE_STATUS_LED) +        HAPTIC_ENABLE_STATUS_LED_WRITE_ACTIVE(); +#endif +    } else { +#if defined(HAPTIC_ENABLE_PIN) +        HAPTIC_ENABLE_PIN_WRITE_INACTIVE(); +#endif +#if defined(HAPTIC_ENABLE_STATUS_LED) +        HAPTIC_ENABLE_STATUS_LED_WRITE_INACTIVE(); +#endif +    } +} + +static void set_haptic_config_enable(bool enabled) { +    haptic_config.enable = enabled; +    update_haptic_enable_gpios(); +} +  void haptic_init(void) {      if (!eeconfig_is_enabled()) {          eeconfig_init(); @@ -44,6 +69,10 @@ void haptic_init(void) {          // or the previous firmware didn't have solenoid enabled,          // and the current one has solenoid enabled.          haptic_reset(); +    } else { +        // Haptic configuration has been loaded through the "raw" union item. +        // This is to execute any side effects of the configuration. +        set_haptic_config_enable(haptic_config.enable);      }  #ifdef SOLENOID_ENABLE      solenoid_setup(); @@ -54,6 +83,12 @@ void haptic_init(void) {      dprintf("DRV2605 driver initialized\n");  #endif      eeconfig_debug_haptic(); +#ifdef HAPTIC_ENABLE_PIN +    setPinOutput(HAPTIC_ENABLE_PIN); +#endif +#ifdef HAPTIC_ENABLE_STATUS_LED +    setPinOutput(HAPTIC_ENABLE_STATUS_LED); +#endif  }  void haptic_task(void) { @@ -69,13 +104,13 @@ void eeconfig_debug_haptic(void) {  }  void haptic_enable(void) { -    haptic_config.enable = 1; +    set_haptic_config_enable(true);      xprintf("haptic_config.enable = %u\n", haptic_config.enable);      eeconfig_update_haptic(haptic_config.raw);  }  void haptic_disable(void) { -    haptic_config.enable = 0; +    set_haptic_config_enable(false);      xprintf("haptic_config.enable = %u\n", haptic_config.enable);      eeconfig_update_haptic(haptic_config.raw);  } @@ -157,7 +192,7 @@ void haptic_dwell_decrease(void) {  }  void haptic_reset(void) { -    haptic_config.enable   = true; +    set_haptic_config_enable(true);      uint8_t feedback       = HAPTIC_FEEDBACK_DEFAULT;      haptic_config.feedback = feedback;  #ifdef DRV2605L @@ -293,3 +328,13 @@ void haptic_shutdown(void) {      solenoid_shutdown();  #endif  } + +void haptic_notify_usb_device_state_change(void) { +    update_haptic_enable_gpios(); +#if defined(HAPTIC_ENABLE_PIN) +    setPinOutput(HAPTIC_ENABLE_PIN); +#endif +#if defined(HAPTIC_ENABLE_STATUS_LED) +    setPinOutput(HAPTIC_ENABLE_STATUS_LED); +#endif +} diff --git a/quantum/haptic.h b/quantum/haptic.h index fc7ca2f3e6..7d70a01333 100644 --- a/quantum/haptic.h +++ b/quantum/haptic.h @@ -75,3 +75,30 @@ void    haptic_cont_decrease(void);  void haptic_play(void);  void haptic_shutdown(void); +void haptic_notify_usb_device_state_change(void); + +#ifdef HAPTIC_ENABLE_PIN_ACTIVE_LOW +#    ifndef HAPTIC_ENABLE_PIN +#        error HAPTIC_ENABLE_PIN not defined +#    endif +#    define HAPTIC_ENABLE_PIN_WRITE_ACTIVE() writePinLow(HAPTIC_ENABLE_PIN) +#    define HAPTIC_ENABLE_PIN_WRITE_INACTIVE() writePinHigh(HAPTIC_ENABLE_PIN) +#else +#    define HAPTIC_ENABLE_PIN_WRITE_ACTIVE() writePinHigh(HAPTIC_ENABLE_PIN) +#    define HAPTIC_ENABLE_PIN_WRITE_INACTIVE() writePinLow(HAPTIC_ENABLE_PIN) +#endif + +#ifdef HAPTIC_ENABLE_STATUS_LED_ACTIVE_LOW +#    ifndef HAPTIC_ENABLE_STATUS_LED +#        error HAPTIC_ENABLE_STATUS_LED not defined +#    endif +#    define HAPTIC_ENABLE_STATUS_LED_WRITE_ACTIVE() writePinLow(HAPTIC_ENABLE_STATUS_LED) +#    define HAPTIC_ENABLE_STATUS_LED_WRITE_INACTIVE() writePinHigh(HAPTIC_ENABLE_STATUS_LED) +#else +#    define HAPTIC_ENABLE_STATUS_LED_WRITE_ACTIVE() writePinHigh(HAPTIC_ENABLE_STATUS_LED) +#    define HAPTIC_ENABLE_STATUS_LED_WRITE_INACTIVE() writePinLow(HAPTIC_ENABLE_STATUS_LED) +#endif + +#ifndef HAPTIC_OFF_IN_LOW_POWER +#    define HAPTIC_OFF_IN_LOW_POWER 0 +#endif diff --git a/quantum/keyboard.c b/quantum/keyboard.c index b98fc64e45..3bca05aab7 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c @@ -40,12 +40,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #ifdef PS2_MOUSE_ENABLE  #    include "ps2_mouse.h"  #endif -#ifdef SERIAL_MOUSE_ENABLE -#    include "serial_mouse.h" -#endif -#ifdef ADB_MOUSE_ENABLE -#    include "adb.h" -#endif  #ifdef RGBLIGHT_ENABLE  #    include "rgblight.h"  #endif @@ -61,12 +55,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #ifdef STENO_ENABLE  #    include "process_steno.h"  #endif -#ifdef SERIAL_LINK_ENABLE -#    include "serial_link/system/serial_link.h" -#endif -#ifdef VISUALIZER_ENABLE -#    include "visualizer/visualizer.h" -#endif  #ifdef POINTING_DEVICE_ENABLE  #    include "pointing_device.h"  #endif @@ -76,12 +64,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #ifdef JOYSTICK_ENABLE  #    include "process_joystick.h"  #endif +#ifdef PROGRAMMABLE_BUTTON_ENABLE +#    include "programmable_button.h" +#endif  #ifdef HD44780_ENABLE  #    include "hd44780.h"  #endif -#ifdef QWIIC_ENABLE -#    include "qwiic.h" -#endif  #ifdef OLED_ENABLE  #    include "oled_driver.h"  #endif @@ -97,9 +85,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #ifdef DIP_SWITCH_ENABLE  #    include "dip_switch.h"  #endif -#ifdef STM32_EEPROM_ENABLE -#    include "eeprom_stm32.h" -#endif  #ifdef EEPROM_DRIVER  #    include "eeprom_driver.h"  #endif @@ -109,6 +94,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #ifdef DIGITIZER_ENABLE  #    include "digitizer.h"  #endif +#ifdef VIRTSER_ENABLE +#    include "virtser.h" +#endif +#ifdef SLEEP_LED_ENABLE +#    include "sleep_led.h" +#endif  static uint32_t last_input_modification_time = 0;  uint32_t        last_input_activity_time(void) { return last_input_modification_time; } @@ -246,9 +237,6 @@ void keyboard_setup(void) {      disable_jtag();  #endif      print_set_sendchar(sendchar); -#ifdef STM32_EEPROM_ENABLE -    EEPROM_Init(); -#endif  #ifdef EEPROM_DRIVER      eeprom_driver_init();  #endif @@ -316,9 +304,6 @@ void keyboard_init(void) {  #if defined(CRC_ENABLE)      crc_init();  #endif -#ifdef QWIIC_ENABLE -    qwiic_init(); -#endif  #ifdef OLED_ENABLE      oled_init(OLED_ROTATION_0);  #endif @@ -328,12 +313,6 @@ void keyboard_init(void) {  #ifdef PS2_MOUSE_ENABLE      ps2_mouse_init();  #endif -#ifdef SERIAL_MOUSE_ENABLE -    serial_mouse_init(); -#endif -#ifdef ADB_MOUSE_ENABLE -    adb_mouse_init(); -#endif  #ifdef BACKLIGHT_ENABLE      backlight_init();  #endif @@ -356,6 +335,12 @@ void keyboard_init(void) {  #ifdef DIP_SWITCH_ENABLE      dip_switch_init();  #endif +#ifdef SLEEP_LED_ENABLE +    sleep_led_init(); +#endif +#ifdef VIRTSER_ENABLE +    virtser_init(); +#endif  #if defined(DEBUG_MATRIX_SCAN_RATE) && defined(CONSOLE_ENABLE)      debug_enable = true; @@ -384,7 +369,6 @@ void switch_events(uint8_t row, uint8_t col, bool pressed) {   *   * * scan matrix   * * handle mouse movements - * * run visualizer code   * * handle midi commands   * * light LEDs   * @@ -473,10 +457,6 @@ MATRIX_LOOP_END:      if (encoders_changed) last_encoder_activity_trigger();  #endif -#ifdef QWIIC_ENABLE -    qwiic_task(); -#endif -  #ifdef OLED_ENABLE      oled_task();  #    if OLED_TIMEOUT > 0 @@ -510,22 +490,6 @@ MATRIX_LOOP_END:      ps2_mouse_task();  #endif -#ifdef SERIAL_MOUSE_ENABLE -    serial_mouse_task(); -#endif - -#ifdef ADB_MOUSE_ENABLE -    adb_mouse_task(); -#endif - -#ifdef SERIAL_LINK_ENABLE -    serial_link_update(); -#endif - -#ifdef VISUALIZER_ENABLE -    visualizer_update(default_layer_state, layer_state, visualizer_get_mods(), host_keyboard_leds()); -#endif -  #ifdef POINTING_DEVICE_ENABLE      pointing_device_task();  #endif @@ -548,6 +512,10 @@ MATRIX_LOOP_END:      digitizer_task();  #endif +#ifdef PROGRAMMABLE_BUTTON_ENABLE +    programmable_button_send(); +#endif +      // update LED      if (led_status != host_keyboard_leds()) {          led_status = host_keyboard_leds(); diff --git a/quantum/keycode.h b/quantum/keycode.h index 8facabd818..38a29b439b 100644 --- a/quantum/keycode.h +++ b/quantum/keycode.h @@ -29,7 +29,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #define IS_ERROR(code) (KC_ROLL_OVER <= (code) && (code) <= KC_UNDEFINED)  #define IS_ANY(code) (KC_A <= (code) && (code) <= 0xFF)  #define IS_KEY(code) (KC_A <= (code) && (code) <= KC_EXSEL) -#define IS_MOD(code) (KC_LCTRL <= (code) && (code) <= KC_RGUI) +#define IS_MOD(code) (KC_LEFT_CTRL <= (code) && (code) <= KC_RIGHT_GUI)  #define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF))  #define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE) @@ -46,10 +46,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #define MOD_BIT(code) (1 << MOD_INDEX(code))  #define MOD_INDEX(code) ((code)&0x07) -#define MOD_MASK_CTRL (MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RCTRL)) -#define MOD_MASK_SHIFT (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) -#define MOD_MASK_ALT (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT)) -#define MOD_MASK_GUI (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI)) +#define MOD_MASK_CTRL (MOD_BIT(KC_LEFT_CTRL) | MOD_BIT(KC_RIGHT_CTRL)) +#define MOD_MASK_SHIFT (MOD_BIT(KC_LEFT_SHIFT) | MOD_BIT(KC_RIGHT_SHIFT)) +#define MOD_MASK_ALT (MOD_BIT(KC_LEFT_ALT) | MOD_BIT(KC_RIGHT_ALT)) +#define MOD_MASK_GUI (MOD_BIT(KC_LEFT_GUI) | MOD_BIT(KC_RIGHT_GUI))  #define MOD_MASK_CS (MOD_MASK_CTRL | MOD_MASK_SHIFT)  #define MOD_MASK_CA (MOD_MASK_CTRL | MOD_MASK_ALT)  #define MOD_MASK_CG (MOD_MASK_CTRL | MOD_MASK_GUI) @@ -67,6 +67,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #define FN_MIN KC_FN0  #define FN_MAX KC_FN31 +// clang-format off +  /*   * Short names for ease of definition of keymap   */ @@ -75,47 +77,55 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #define KC_TRNS KC_TRANSPARENT  /* Punctuation */ -#define KC_ENT KC_ENTER -#define KC_ESC KC_ESCAPE -#define KC_BSPC KC_BSPACE -#define KC_SPC KC_SPACE +#define KC_ENT  KC_ENTER +#define KC_ESC  KC_ESCAPE +#define KC_BSPC KC_BACKSPACE +#define KC_SPC  KC_SPACE  #define KC_MINS KC_MINUS -#define KC_EQL KC_EQUAL -#define KC_LBRC KC_LBRACKET -#define KC_RBRC KC_RBRACKET -#define KC_BSLS KC_BSLASH +#define KC_EQL  KC_EQUAL +#define KC_LBRC KC_LEFT_BRACKET +#define KC_RBRC KC_RIGHT_BRACKET +#define KC_BSLS KC_BACKSLASH  #define KC_NUHS KC_NONUS_HASH -#define KC_SCLN KC_SCOLON +#define KC_SCLN KC_SEMICOLON  #define KC_QUOT KC_QUOTE -#define KC_GRV KC_GRAVE +#define KC_GRV  KC_GRAVE  #define KC_COMM KC_COMMA  #define KC_SLSH KC_SLASH -#define KC_NUBS KC_NONUS_BSLASH +#define KC_NUBS KC_NONUS_BACKSLASH  /* Lock Keys */ -#define KC_CLCK KC_CAPSLOCK -#define KC_CAPS KC_CAPSLOCK -#define KC_SLCK KC_SCROLLLOCK -#define KC_NLCK KC_NUMLOCK -#define KC_LCAP KC_LOCKING_CAPS -#define KC_LNUM KC_LOCKING_NUM -#define KC_LSCR KC_LOCKING_SCROLL +#define KC_CAPS KC_CAPS_LOCK +#define KC_SCRL KC_SCROLL_LOCK +#define KC_NUM  KC_NUM_LOCK +#define KC_LCAP KC_LOCKING_CAPS_LOCK +#define KC_LNUM KC_LOCKING_NUM_LOCK +#define KC_LSCR KC_LOCKING_SCROLL_LOCK  /* Commands */ -#define KC_PSCR KC_PSCREEN +#define KC_PSCR KC_PRINT_SCREEN  #define KC_PAUS KC_PAUSE -#define KC_BRK KC_PAUSE -#define KC_INS KC_INSERT -#define KC_DEL KC_DELETE -#define KC_PGDN KC_PGDOWN +#define KC_BRK  KC_PAUSE +#define KC_INS  KC_INSERT +#define KC_PGUP KC_PAGE_UP +#define KC_DEL  KC_DELETE +#define KC_PGDN KC_PAGE_DOWN  #define KC_RGHT KC_RIGHT -#define KC_APP KC_APPLICATION +#define KC_APP  KC_APPLICATION  #define KC_EXEC KC_EXECUTE  #define KC_SLCT KC_SELECT  #define KC_AGIN KC_AGAIN  #define KC_PSTE KC_PASTE -#define KC_ERAS KC_ALT_ERASE -#define KC_CLR KC_CLEAR +#define KC_ERAS KC_ALTERNATE_ERASE +#define KC_SYRQ KC_SYSTEM_REQUEST +#define KC_CNCL KC_CANCEL +#define KC_CLR  KC_CLEAR +#define KC_PRIR KC_PRIOR +#define KC_RETN KC_RETURN +#define KC_SEPR KC_SEPARATOR +#define KC_CLAG KC_CLEAR_AGAIN +#define KC_CRSL KC_CRSEL +#define KC_EXSL KC_EXSEL  /* Keypad */  #define KC_PSLS KC_KP_SLASH @@ -123,47 +133,59 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #define KC_PMNS KC_KP_MINUS  #define KC_PPLS KC_KP_PLUS  #define KC_PENT KC_KP_ENTER -#define KC_P1 KC_KP_1 -#define KC_P2 KC_KP_2 -#define KC_P3 KC_KP_3 -#define KC_P4 KC_KP_4 -#define KC_P5 KC_KP_5 -#define KC_P6 KC_KP_6 -#define KC_P7 KC_KP_7 -#define KC_P8 KC_KP_8 -#define KC_P9 KC_KP_9 -#define KC_P0 KC_KP_0 +#define KC_P1   KC_KP_1 +#define KC_P2   KC_KP_2 +#define KC_P3   KC_KP_3 +#define KC_P4   KC_KP_4 +#define KC_P5   KC_KP_5 +#define KC_P6   KC_KP_6 +#define KC_P7   KC_KP_7 +#define KC_P8   KC_KP_8 +#define KC_P9   KC_KP_9 +#define KC_P0   KC_KP_0  #define KC_PDOT KC_KP_DOT  #define KC_PEQL KC_KP_EQUAL  #define KC_PCMM KC_KP_COMMA -/* Japanese specific */ -#define KC_ZKHK KC_GRAVE -#define KC_RO KC_INT1 -#define KC_KANA KC_INT2 -#define KC_JYEN KC_INT3 -#define KC_HENK KC_INT4 -#define KC_MHEN KC_INT5 - -/* Korean specific */ -#define KC_HAEN KC_LANG1 -#define KC_HANJ KC_LANG2 +/* Language Specific */ +#define KC_INT1 KC_INTERNATIONAL_1 +#define KC_INT2 KC_INTERNATIONAL_2 +#define KC_INT3 KC_INTERNATIONAL_3 +#define KC_INT4 KC_INTERNATIONAL_4 +#define KC_INT5 KC_INTERNATIONAL_5 +#define KC_INT6 KC_INTERNATIONAL_6 +#define KC_INT7 KC_INTERNATIONAL_7 +#define KC_INT8 KC_INTERNATIONAL_8 +#define KC_INT9 KC_INTERNATIONAL_9 +#define KC_LNG1 KC_LANGUAGE_1 +#define KC_LNG2 KC_LANGUAGE_2 +#define KC_LNG3 KC_LANGUAGE_3 +#define KC_LNG4 KC_LANGUAGE_4 +#define KC_LNG5 KC_LANGUAGE_5 +#define KC_LNG6 KC_LANGUAGE_6 +#define KC_LNG7 KC_LANGUAGE_7 +#define KC_LNG8 KC_LANGUAGE_8 +#define KC_LNG9 KC_LANGUAGE_9  /* Modifiers */ -#define KC_LCTL KC_LCTRL -#define KC_LSFT KC_LSHIFT -#define KC_LOPT KC_LALT -#define KC_LCMD KC_LGUI -#define KC_LWIN KC_LGUI -#define KC_RCTL KC_RCTRL -#define KC_RSFT KC_RSHIFT -#define KC_ALGR KC_RALT -#define KC_ROPT KC_RALT -#define KC_RCMD KC_RGUI -#define KC_RWIN KC_RGUI +#define KC_LCTL KC_LEFT_CTRL +#define KC_LSFT KC_LEFT_SHIFT +#define KC_LALT KC_LEFT_ALT +#define KC_LOPT KC_LEFT_ALT +#define KC_LGUI KC_LEFT_GUI +#define KC_LCMD KC_LEFT_GUI +#define KC_LWIN KC_LEFT_GUI +#define KC_RCTL KC_RIGHT_CTRL +#define KC_RSFT KC_RIGHT_SHIFT +#define KC_RALT KC_RIGHT_ALT +#define KC_ALGR KC_RIGHT_ALT +#define KC_ROPT KC_RIGHT_ALT +#define KC_RGUI KC_RIGHT_GUI +#define KC_RCMD KC_RIGHT_GUI +#define KC_RWIN KC_RIGHT_GUI  /* Generic Desktop Page (0x01) */ -#define KC_PWR KC_SYSTEM_POWER +#define KC_PWR  KC_SYSTEM_POWER  #define KC_SLEP KC_SYSTEM_SLEEP  #define KC_WAKE KC_SYSTEM_WAKE @@ -193,7 +215,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  /* System Specific */  #define KC_BRMU KC_PAUSE -#define KC_BRMD KC_SCROLLLOCK +#define KC_BRMD KC_SCROLL_LOCK  /* Mouse Keys */  #define KC_MS_U KC_MS_UP @@ -216,6 +238,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #define KC_ACL1 KC_MS_ACCEL1  #define KC_ACL2 KC_MS_ACCEL2 +// clang-format on +  /* Keyboard/Keypad Page (0x07) */  enum hid_keyboard_keypad_usage {      KC_NO = 0x00, @@ -260,22 +284,22 @@ enum hid_keyboard_keypad_usage {      KC_0,      KC_ENTER,      KC_ESCAPE, -    KC_BSPACE, +    KC_BACKSPACE,      KC_TAB,      KC_SPACE,      KC_MINUS,      KC_EQUAL, -    KC_LBRACKET, -    KC_RBRACKET,  // 0x30 -    KC_BSLASH, +    KC_LEFT_BRACKET, +    KC_RIGHT_BRACKET,  // 0x30 +    KC_BACKSLASH,      KC_NONUS_HASH, -    KC_SCOLON, +    KC_SEMICOLON,      KC_QUOTE,      KC_GRAVE,      KC_COMMA,      KC_DOT,      KC_SLASH, -    KC_CAPSLOCK, +    KC_CAPS_LOCK,      KC_F1,      KC_F2,      KC_F3, @@ -288,20 +312,20 @@ enum hid_keyboard_keypad_usage {      KC_F10,      KC_F11,      KC_F12, -    KC_PSCREEN, -    KC_SCROLLLOCK, +    KC_PRINT_SCREEN, +    KC_SCROLL_LOCK,      KC_PAUSE,      KC_INSERT,      KC_HOME, -    KC_PGUP, +    KC_PAGE_UP,      KC_DELETE,      KC_END, -    KC_PGDOWN, +    KC_PAGE_DOWN,      KC_RIGHT,      KC_LEFT,  // 0x50      KC_DOWN,      KC_UP, -    KC_NUMLOCK, +    KC_NUM_LOCK,      KC_KP_SLASH,      KC_KP_ASTERISK,      KC_KP_MINUS, @@ -318,9 +342,9 @@ enum hid_keyboard_keypad_usage {      KC_KP_9,      KC_KP_0,      KC_KP_DOT, -    KC_NONUS_BSLASH, +    KC_NONUS_BACKSLASH,      KC_APPLICATION, -    KC_POWER, +    KC_KB_POWER,      KC_KP_EQUAL,      KC_F13,      KC_F14, @@ -345,34 +369,34 @@ enum hid_keyboard_keypad_usage {      KC_COPY,      KC_PASTE,      KC_FIND, -    KC__MUTE, -    KC__VOLUP,  // 0x80 -    KC__VOLDOWN, -    KC_LOCKING_CAPS, -    KC_LOCKING_NUM, -    KC_LOCKING_SCROLL, +    KC_KB_MUTE, +    KC_KB_VOLUME_UP,  // 0x80 +    KC_KB_VOLUME_DOWN, +    KC_LOCKING_CAPS_LOCK, +    KC_LOCKING_NUM_LOCK, +    KC_LOCKING_SCROLL_LOCK,      KC_KP_COMMA,      KC_KP_EQUAL_AS400, -    KC_INT1, -    KC_INT2, -    KC_INT3, -    KC_INT4, -    KC_INT5, -    KC_INT6, -    KC_INT7, -    KC_INT8, -    KC_INT9, -    KC_LANG1,  // 0x90 -    KC_LANG2, -    KC_LANG3, -    KC_LANG4, -    KC_LANG5, -    KC_LANG6, -    KC_LANG7, -    KC_LANG8, -    KC_LANG9, -    KC_ALT_ERASE, -    KC_SYSREQ, +    KC_INTERNATIONAL_1, +    KC_INTERNATIONAL_2, +    KC_INTERNATIONAL_3, +    KC_INTERNATIONAL_4, +    KC_INTERNATIONAL_5, +    KC_INTERNATIONAL_6, +    KC_INTERNATIONAL_7, +    KC_INTERNATIONAL_8, +    KC_INTERNATIONAL_9, +    KC_LANGUAGE_1,  // 0x90 +    KC_LANGUAGE_2, +    KC_LANGUAGE_3, +    KC_LANGUAGE_4, +    KC_LANGUAGE_5, +    KC_LANGUAGE_6, +    KC_LANGUAGE_7, +    KC_LANGUAGE_8, +    KC_LANGUAGE_9, +    KC_ALTERNATE_ERASE, +    KC_SYSTEM_REQUEST,      KC_CANCEL,      KC_CLEAR,      KC_PRIOR, @@ -397,12 +421,12 @@ enum hid_keyboard_keypad_usage {    KC_DECIMAL_SEPARATOR,    KC_CURRENCY_UNIT,    KC_CURRENCY_SUB_UNIT, -  KC_KP_LPAREN, -  KC_KP_RPAREN, -  KC_KP_LCBRACKET, -  KC_KP_RCBRACKET, +  KC_KP_LEFT_PARENTHESIS, +  KC_KP_RIGHT_PARENTHESIS, +  KC_KP_LEFT_BRACE, +  KC_KP_RIGHT_BRACE,    KC_KP_TAB, -  KC_KP_BSPACE, +  KC_KP_BACKSPACE,    KC_KP_A,    KC_KP_B,    KC_KP_C, @@ -411,17 +435,17 @@ enum hid_keyboard_keypad_usage {    KC_KP_F,    KC_KP_XOR,    KC_KP_HAT, -  KC_KP_PERC, -  KC_KP_LT, -  KC_KP_GT, +  KC_KP_PERCENT, +  KC_KP_LESS_THAN, +  KC_KP_GREATER_THAN,    KC_KP_AND, -  KC_KP_LAZYAND, +  KC_KP_LAZY_AND,    KC_KP_OR, -  KC_KP_LAZYOR, +  KC_KP_LAZY_OR,    KC_KP_COLON,    KC_KP_HASH,    KC_KP_SPACE, -  KC_KP_ATMARK, +  KC_KP_AT,    KC_KP_EXCLAMATION,    KC_KP_MEM_STORE,        //0xD0    KC_KP_MEM_RECALL, @@ -440,14 +464,14 @@ enum hid_keyboard_keypad_usage {  #endif      /* Modifiers */ -    KC_LCTRL = 0xE0, -    KC_LSHIFT, -    KC_LALT, -    KC_LGUI, -    KC_RCTRL, -    KC_RSHIFT, -    KC_RALT, -    KC_RGUI +    KC_LEFT_CTRL = 0xE0, +    KC_LEFT_SHIFT, +    KC_LEFT_ALT, +    KC_LEFT_GUI, +    KC_RIGHT_CTRL, +    KC_RIGHT_SHIFT, +    KC_RIGHT_ALT, +    KC_RIGHT_GUI      // **********************************************      // * 0xF0-0xFF are unallocated in the HID spec. * @@ -558,3 +582,5 @@ enum mouse_keys {      KC_MS_ACCEL1,      KC_MS_ACCEL2  // 0xFF  }; + +#include "keycode_legacy.h" diff --git a/quantum/keycode_config.c b/quantum/keycode_config.c index f340905eab..dd2a17e242 100644 --- a/quantum/keycode_config.c +++ b/quantum/keycode_config.c @@ -25,89 +25,89 @@ extern keymap_config_t keymap_config;   */  uint16_t keycode_config(uint16_t keycode) {      switch (keycode) { -        case KC_CAPSLOCK: -        case KC_LOCKING_CAPS: +        case KC_CAPS_LOCK: +        case KC_LOCKING_CAPS_LOCK:              if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) { -                return KC_LCTL; +                return KC_LEFT_CTRL;              }              return keycode; -        case KC_LCTL: +        case KC_LEFT_CTRL:              if (keymap_config.swap_control_capslock) { -                return KC_CAPSLOCK; +                return KC_CAPS_LOCK;              }              if (keymap_config.swap_lctl_lgui) {                  if (keymap_config.no_gui) {                      return KC_NO;                  } -                return KC_LGUI; +                return KC_LEFT_GUI;              } -            return KC_LCTL; -        case KC_LALT: +            return KC_LEFT_CTRL; +        case KC_LEFT_ALT:              if (keymap_config.swap_lalt_lgui) {                  if (keymap_config.no_gui) {                      return KC_NO;                  } -                return KC_LGUI; +                return KC_LEFT_GUI;              } -            return KC_LALT; -        case KC_LGUI: +            return KC_LEFT_ALT; +        case KC_LEFT_GUI:              if (keymap_config.swap_lalt_lgui) { -                return KC_LALT; +                return KC_LEFT_ALT;              }              if (keymap_config.swap_lctl_lgui) { -                return KC_LCTRL; +                return KC_LEFT_CTRL;              }              if (keymap_config.no_gui) {                  return KC_NO;              } -            return KC_LGUI; -        case KC_RCTL: +            return KC_LEFT_GUI; +        case KC_RIGHT_CTRL:              if (keymap_config.swap_rctl_rgui) {                  if (keymap_config.no_gui) {                      return KC_NO;                  } -                return KC_RGUI; +                return KC_RIGHT_GUI;              } -            return KC_RCTL; -        case KC_RALT: +            return KC_RIGHT_CTRL; +        case KC_RIGHT_ALT:              if (keymap_config.swap_ralt_rgui) {                  if (keymap_config.no_gui) {                      return KC_NO;                  } -                return KC_RGUI; +                return KC_RIGHT_GUI;              } -            return KC_RALT; -        case KC_RGUI: +            return KC_RIGHT_ALT; +        case KC_RIGHT_GUI:              if (keymap_config.swap_ralt_rgui) { -                return KC_RALT; +                return KC_RIGHT_ALT;              }              if (keymap_config.swap_rctl_rgui) { -                return KC_RCTL; +                return KC_RIGHT_CTRL;              }              if (keymap_config.no_gui) {                  return KC_NO;              } -            return KC_RGUI; +            return KC_RIGHT_GUI;          case KC_GRAVE:              if (keymap_config.swap_grave_esc) { -                return KC_ESC; +                return KC_ESCAPE;              }              return KC_GRAVE; -        case KC_ESC: +        case KC_ESCAPE:              if (keymap_config.swap_grave_esc) {                  return KC_GRAVE;              } -            return KC_ESC; -        case KC_BSLASH: +            return KC_ESCAPE; +        case KC_BACKSLASH:              if (keymap_config.swap_backslash_backspace) { -                return KC_BSPACE; +                return KC_BACKSPACE;              } -            return KC_BSLASH; -        case KC_BSPACE: +            return KC_BACKSLASH; +        case KC_BACKSPACE:              if (keymap_config.swap_backslash_backspace) { -                return KC_BSLASH; +                return KC_BACKSLASH;              } -            return KC_BSPACE; +            return KC_BACKSPACE;          default:              return keycode;      } diff --git a/quantum/keycode_legacy.h b/quantum/keycode_legacy.h new file mode 100644 index 0000000000..0317a05534 --- /dev/null +++ b/quantum/keycode_legacy.h @@ -0,0 +1,53 @@ +#pragma once + +// clang-format off + +// These keycode names have been deprecated + +#define KC_BSPACE         KC_BACKSPACE +#define KC_LBRACKET       KC_LEFT_BRACKET +#define KC_RBRACKET       KC_RIGHT_BRACKET +#define KC_BSLASH         KC_BACKSLASH +#define KC_SCOLON         KC_SEMICOLON +#define KC_CAPSLOCK       KC_CAPS_LOCK +#define KC_PSCREEN        KC_PRINT_SCREEN +#define KC_SCROLLLOCK     KC_SCROLL_LOCK +#define KC_PGDOWN         KC_PAGE_DOWN +#define KC_NUMLOCK        KC_NUM_LOCK +#define KC_NONUS_BSLASH   KC_NONUS_BACKSLASH +#define KC_POWER          KC_KB_POWER +#define KC__MUTE          KC_KB_MUTE +#define KC__VOLUP         KC_KB_VOLUME_UP +#define KC__VOLDOWN       KC_KB_VOLUME_DOWN +#define KC_LOCKING_CAPS   KC_LOCKING_CAPS_LOCK +#define KC_LOCKING_NUM    KC_LOCKING_NUM_LOCK +#define KC_LOCKING_SCROLL KC_LOCKING_SCROLL_LOCK +#define KC_LANG1          KC_LANGUAGE_1 +#define KC_LANG2          KC_LANGUAGE_2 +#define KC_LANG3          KC_LANGUAGE_3 +#define KC_LANG4          KC_LANGUAGE_4 +#define KC_LANG5          KC_LANGUAGE_5 +#define KC_LANG6          KC_LANGUAGE_6 +#define KC_LANG7          KC_LANGUAGE_7 +#define KC_LANG8          KC_LANGUAGE_8 +#define KC_LANG9          KC_LANGUAGE_9 +#define KC_ALT_ERASE      KC_ALTERNATE_ERASE +#define KC_SYSREQ         KC_SYSTEM_REQUEST + +#define KC_LCTRL          KC_LEFT_CTRL +#define KC_LSHIFT         KC_LEFT_SHIFT +#define KC_RCTRL          KC_RIGHT_CTRL +#define KC_RSHIFT         KC_RIGHT_SHIFT + +#define KC_ZKHK KC_GRAVE +#define KC_RO   KC_INTERNATIONAL_1 +#define KC_KANA KC_INTERNATIONAL_2 +#define KC_JYEN KC_INTERNATIONAL_3 +#define KC_HENK KC_INTERNATIONAL_4 +#define KC_MHEN KC_INTERNATIONAL_5 +#define KC_HAEN KC_LANGUAGE_1 +#define KC_HANJ KC_LANGUAGE_2 + +#define KC_CLCK KC_CAPS_LOCK +#define KC_SLCK KC_SCROLL_LOCK +#define KC_NLCK KC_NUM_LOCK diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 780c71ab9b..5007f15f11 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -56,7 +56,7 @@ action_t action_for_keycode(uint16_t keycode) {      switch (keycode) {          case KC_A ... KC_EXSEL: -        case KC_LCTRL ... KC_RGUI: +        case KC_LEFT_CTRL ... KC_RIGHT_GUI:              action.code = ACTION_KEY(keycode);              break;  #ifdef EXTRAKEY_ENABLE @@ -72,7 +72,7 @@ action_t action_for_keycode(uint16_t keycode) {              action.code = ACTION_MOUSEKEY(keycode);              break;  #endif -        case KC_TRNS: +        case KC_TRANSPARENT:              action.code = ACTION_TRANSPARENT;              break;          case QK_MODS ... QK_MODS_MAX:; diff --git a/quantum/keymap_extras/keymap_korean.h b/quantum/keymap_extras/keymap_korean.h index 23d235ef09..74be122dad 100644 --- a/quantum/keymap_extras/keymap_korean.h +++ b/quantum/keymap_extras/keymap_korean.h @@ -85,8 +85,8 @@  #define KR_DOT  KC_DOT  // .  #define KR_SLSH KC_SLSH // /  // Row 5 -#define KR_HANJ KC_LANG2 // Hanja (한자) -#define KR_HAEN KC_LANG1 // Han ↔ Yeong (한 ↔ 영) +#define KR_HANJ KC_LNG2 // Hanja (한자) +#define KR_HAEN KC_LNG1 // Han ↔ Yeong (한 ↔ 영)  /* Shifted symbols   * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ diff --git a/quantum/keymap_extras/keymap_steno.h b/quantum/keymap_extras/keymap_steno.h index ab95b43fdd..310aa07409 100644 --- a/quantum/keymap_extras/keymap_steno.h +++ b/quantum/keymap_extras/keymap_steno.h @@ -74,8 +74,7 @@ enum steno_keycodes {  };  #ifdef STENO_COMBINEDMAP -enum steno_combined_keycodes -{ +enum steno_combined_keycodes {      STN_S3 = QK_STENO_COMB,      STN_TKL,      STN_PWL, diff --git a/quantum/keymap_extras/keymap_turkish_f.h b/quantum/keymap_extras/keymap_turkish_f.h index 226f8cbeb0..f86ef21546 100644 --- a/quantum/keymap_extras/keymap_turkish_f.h +++ b/quantum/keymap_extras/keymap_turkish_f.h @@ -111,7 +111,7 @@  #define TR_LPRN S(TR_8)    // (  #define TR_RPRN S(TR_9)    // )  #define TR_EQL  S(TR_0)    // = -#define TR_QUES S(TR_ASTR) // ? +#define TR_QUES S(TR_SLSH) // ?  #define TR_UNDS S(TR_MINS) // _  // Row 4  #define TR_RABK S(TR_LABK) // > diff --git a/quantum/led_matrix/animations/alpha_mods_anim.h b/quantum/led_matrix/animations/alpha_mods_anim.h index 14038cd082..c82b2aa388 100644 --- a/quantum/led_matrix/animations/alpha_mods_anim.h +++ b/quantum/led_matrix/animations/alpha_mods_anim.h @@ -17,7 +17,7 @@ bool ALPHAS_MODS(effect_params_t* params) {              led_matrix_set_value(i, val1);          }      } -    return led_max < DRIVER_LED_TOTAL; +    return led_matrix_check_finished_leds(led_max);  }  #    endif  // LED_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/led_matrix/animations/breathing_anim.h b/quantum/led_matrix/animations/breathing_anim.h index e3f600c45c..d9cc2de23b 100644 --- a/quantum/led_matrix/animations/breathing_anim.h +++ b/quantum/led_matrix/animations/breathing_anim.h @@ -12,7 +12,7 @@ bool BREATHING(effect_params_t* params) {          LED_MATRIX_TEST_LED_FLAGS();          led_matrix_set_value(i, val);      } -    return led_max < DRIVER_LED_TOTAL; +    return led_matrix_check_finished_leds(led_max);  }  #    endif  // LED_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/led_matrix/animations/runners/effect_runner_dx_dy.h b/quantum/led_matrix/animations/runners/effect_runner_dx_dy.h index ef97631b90..fa9b7dbbfa 100644 --- a/quantum/led_matrix/animations/runners/effect_runner_dx_dy.h +++ b/quantum/led_matrix/animations/runners/effect_runner_dx_dy.h @@ -12,5 +12,5 @@ bool effect_runner_dx_dy(effect_params_t* params, dx_dy_f effect_func) {          int16_t dy = g_led_config.point[i].y - k_led_matrix_center.y;          led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, dx, dy, time));      } -    return led_max < DRIVER_LED_TOTAL; +    return led_matrix_check_finished_leds(led_max);  } diff --git a/quantum/led_matrix/animations/runners/effect_runner_dx_dy_dist.h b/quantum/led_matrix/animations/runners/effect_runner_dx_dy_dist.h index 5ef5938be0..061a5f07fe 100644 --- a/quantum/led_matrix/animations/runners/effect_runner_dx_dy_dist.h +++ b/quantum/led_matrix/animations/runners/effect_runner_dx_dy_dist.h @@ -13,5 +13,5 @@ bool effect_runner_dx_dy_dist(effect_params_t* params, dx_dy_dist_f effect_func)          uint8_t dist = sqrt16(dx * dx + dy * dy);          led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, dx, dy, dist, time));      } -    return led_max < DRIVER_LED_TOTAL; +    return led_matrix_check_finished_leds(led_max);  } diff --git a/quantum/led_matrix/animations/runners/effect_runner_i.h b/quantum/led_matrix/animations/runners/effect_runner_i.h index b3015759be..f6f8c0dee0 100644 --- a/quantum/led_matrix/animations/runners/effect_runner_i.h +++ b/quantum/led_matrix/animations/runners/effect_runner_i.h @@ -10,5 +10,5 @@ bool effect_runner_i(effect_params_t* params, i_f effect_func) {          LED_MATRIX_TEST_LED_FLAGS();          led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, i, time));      } -    return led_max < DRIVER_LED_TOTAL; +    return led_matrix_check_finished_leds(led_max);  } diff --git a/quantum/led_matrix/animations/runners/effect_runner_reactive.h b/quantum/led_matrix/animations/runners/effect_runner_reactive.h index 4369ea8c49..be3090aa53 100644 --- a/quantum/led_matrix/animations/runners/effect_runner_reactive.h +++ b/quantum/led_matrix/animations/runners/effect_runner_reactive.h @@ -22,7 +22,7 @@ bool effect_runner_reactive(effect_params_t* params, reactive_f effect_func) {          uint16_t offset = scale16by8(tick, led_matrix_eeconfig.speed);          led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, offset));      } -    return led_max < DRIVER_LED_TOTAL; +    return led_matrix_check_finished_leds(led_max);  }  #endif  // LED_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/led_matrix/animations/runners/effect_runner_reactive_splash.h b/quantum/led_matrix/animations/runners/effect_runner_reactive_splash.h index d6eb9731ee..f6ffc825a1 100644 --- a/quantum/led_matrix/animations/runners/effect_runner_reactive_splash.h +++ b/quantum/led_matrix/animations/runners/effect_runner_reactive_splash.h @@ -20,7 +20,7 @@ bool effect_runner_reactive_splash(uint8_t start, effect_params_t* params, react          }          led_matrix_set_value(i, scale8(val, led_matrix_eeconfig.val));      } -    return led_max < DRIVER_LED_TOTAL; +    return led_matrix_check_finished_leds(led_max);  }  #endif  // LED_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/led_matrix/animations/runners/effect_runner_sin_cos_i.h b/quantum/led_matrix/animations/runners/effect_runner_sin_cos_i.h index 4a5219abd1..3145e27139 100644 --- a/quantum/led_matrix/animations/runners/effect_runner_sin_cos_i.h +++ b/quantum/led_matrix/animations/runners/effect_runner_sin_cos_i.h @@ -12,5 +12,5 @@ bool effect_runner_sin_cos_i(effect_params_t* params, sin_cos_i_f effect_func) {          LED_MATRIX_TEST_LED_FLAGS();          led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, cos_value, sin_value, i, time));      } -    return led_max < DRIVER_LED_TOTAL; +    return led_matrix_check_finished_leds(led_max);  } diff --git a/quantum/led_matrix/animations/solid_anim.h b/quantum/led_matrix/animations/solid_anim.h index 4c9e43c581..c728dbcc98 100644 --- a/quantum/led_matrix/animations/solid_anim.h +++ b/quantum/led_matrix/animations/solid_anim.h @@ -9,7 +9,7 @@ bool SOLID(effect_params_t* params) {          LED_MATRIX_TEST_LED_FLAGS();          led_matrix_set_value(i, val);      } -    return led_max < DRIVER_LED_TOTAL; +    return led_matrix_check_finished_leds(led_max);  }  #endif  // LED_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c index 50510e49aa..8d6a56f27f 100644 --- a/quantum/led_matrix/led_matrix.c +++ b/quantum/led_matrix/led_matrix.c @@ -33,14 +33,6 @@ const led_point_t k_led_matrix_center = {112, 32};  const led_point_t k_led_matrix_center = LED_MATRIX_CENTER;  #endif -// clang-format off -#ifndef LED_MATRIX_IMMEDIATE_EEPROM -#    define led_eeconfig_update(v) led_update_eeprom |= v -#else -#    define led_eeconfig_update(v) if (v) eeconfig_update_led_matrix() -#endif -// clang-format on -  // Generic effect runners  #include "led_matrix_runners.inc" @@ -107,7 +99,6 @@ last_hit_t g_last_hit_tracker;  // internals  static bool            suspend_state     = false; -static bool            led_update_eeprom = false;  static uint8_t         led_last_enable   = UINT8_MAX;  static uint8_t         led_last_effect   = UINT8_MAX;  static effect_params_t led_effect_params = {0, LED_FLAG_ALL, false}; @@ -127,9 +118,9 @@ static last_hit_t last_hit_buffer;  const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT;  #endif -void eeconfig_read_led_matrix(void) { eeprom_read_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); } +EECONFIG_DEBOUNCE_HELPER(led_matrix, EECONFIG_LED_MATRIX, led_matrix_eeconfig); -void eeconfig_update_led_matrix(void) { eeprom_update_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); } +void eeconfig_update_led_matrix(void) { eeconfig_flush_led_matrix(true); }  void eeconfig_update_led_matrix_default(void) {      dprintf("eeconfig_update_led_matrix_default\n"); @@ -138,7 +129,7 @@ void eeconfig_update_led_matrix_default(void) {      led_matrix_eeconfig.val    = LED_MATRIX_STARTUP_VAL;      led_matrix_eeconfig.speed  = LED_MATRIX_STARTUP_SPD;      led_matrix_eeconfig.flags  = LED_FLAG_ALL; -    eeconfig_update_led_matrix(); +    eeconfig_flush_led_matrix(true);  }  void eeconfig_debug_led_matrix(void) { @@ -165,20 +156,10 @@ uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *l  void led_matrix_update_pwm_buffers(void) { led_matrix_driver.flush(); }  void led_matrix_set_value(int index, uint8_t value) { -#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) -    if (!is_keyboard_left() && index >= k_led_matrix_split[0]) -#    ifdef USE_CIE1931_CURVE -        led_matrix_driver.set_value(index - k_led_matrix_split[0], pgm_read_byte(&CIE1931_CURVE[value])); -#    else -        led_matrix_driver.set_value(index - k_led_matrix_split[0], value); -#    endif -    else if (is_keyboard_left() && index < k_led_matrix_split[0]) -#endif  #ifdef USE_CIE1931_CURVE -        led_matrix_driver.set_value(index, pgm_read_byte(&CIE1931_CURVE[value])); -#else -    led_matrix_driver.set_value(index, value); +    value = pgm_read_byte(&CIE1931_CURVE[value]);  #endif +    led_matrix_driver.set_value(index, value);  }  void led_matrix_set_value_all(uint8_t value) { @@ -279,9 +260,8 @@ static void led_task_timers(void) {  }  static void led_task_sync(void) { +    eeconfig_flush_led_matrix(false);      // next task -    if (led_update_eeprom) eeconfig_update_led_matrix(); -    led_update_eeprom = false;      if (sync_timer_elapsed32(g_led_timer) >= LED_MATRIX_LED_FLUSH_LIMIT) led_task_state = STARTING;  } @@ -449,7 +429,7 @@ void led_matrix_init(void) {          eeconfig_update_led_matrix_default();      } -    eeconfig_read_led_matrix(); +    eeconfig_init_led_matrix();      if (!led_matrix_eeconfig.mode) {          dprintf("led_matrix_init_drivers led_matrix_eeconfig.mode = 0. Write default values to EEPROM.\n");          eeconfig_update_led_matrix_default(); @@ -472,7 +452,7 @@ bool led_matrix_get_suspend_state(void) { return suspend_state; }  void led_matrix_toggle_eeprom_helper(bool write_to_eeprom) {      led_matrix_eeconfig.enable ^= 1;      led_task_state = STARTING; -    led_eeconfig_update(write_to_eeprom); +    eeconfig_flag_led_matrix(write_to_eeprom);      dprintf("led matrix toggle [%s]: led_matrix_eeconfig.enable = %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.enable);  }  void led_matrix_toggle_noeeprom(void) { led_matrix_toggle_eeprom_helper(false); } @@ -480,7 +460,7 @@ void led_matrix_toggle(void) { led_matrix_toggle_eeprom_helper(true); }  void led_matrix_enable(void) {      led_matrix_enable_noeeprom(); -    led_eeconfig_update(true); +    eeconfig_flag_led_matrix(true);  }  void led_matrix_enable_noeeprom(void) { @@ -490,7 +470,7 @@ void led_matrix_enable_noeeprom(void) {  void led_matrix_disable(void) {      led_matrix_disable_noeeprom(); -    led_eeconfig_update(true); +    eeconfig_flag_led_matrix(true);  }  void led_matrix_disable_noeeprom(void) { @@ -512,7 +492,7 @@ void led_matrix_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {          led_matrix_eeconfig.mode = mode;      }      led_task_state = STARTING; -    led_eeconfig_update(write_to_eeprom); +    eeconfig_flag_led_matrix(write_to_eeprom);      dprintf("led matrix mode [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.mode);  }  void led_matrix_mode_noeeprom(uint8_t mode) { led_matrix_mode_eeprom_helper(mode, false); } @@ -539,7 +519,7 @@ void led_matrix_set_val_eeprom_helper(uint8_t val, bool write_to_eeprom) {          return;      }      led_matrix_eeconfig.val = (val > LED_MATRIX_MAXIMUM_BRIGHTNESS) ? LED_MATRIX_MAXIMUM_BRIGHTNESS : val; -    led_eeconfig_update(write_to_eeprom); +    eeconfig_flag_led_matrix(write_to_eeprom);      dprintf("led matrix set val [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.val);  }  void led_matrix_set_val_noeeprom(uint8_t val) { led_matrix_set_val_eeprom_helper(val, false); } @@ -557,7 +537,7 @@ void led_matrix_decrease_val(void) { led_matrix_decrease_val_helper(true); }  void led_matrix_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) {      led_matrix_eeconfig.speed = speed; -    led_eeconfig_update(write_to_eeprom); +    eeconfig_flag_led_matrix(write_to_eeprom);      dprintf("led matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.speed);  }  void led_matrix_set_speed_noeeprom(uint8_t speed) { led_matrix_set_speed_eeprom_helper(speed, false); } diff --git a/quantum/led_matrix/led_matrix.h b/quantum/led_matrix/led_matrix.h index a7a1c983f7..5386744430 100644 --- a/quantum/led_matrix/led_matrix.h +++ b/quantum/led_matrix/led_matrix.h @@ -38,14 +38,33 @@  #endif  #if defined(LED_MATRIX_LED_PROCESS_LIMIT) && LED_MATRIX_LED_PROCESS_LIMIT > 0 && LED_MATRIX_LED_PROCESS_LIMIT < DRIVER_LED_TOTAL -#    define LED_MATRIX_USE_LIMITS(min, max)                        \ -        uint8_t min = LED_MATRIX_LED_PROCESS_LIMIT * params->iter; \ -        uint8_t max = min + LED_MATRIX_LED_PROCESS_LIMIT;          \ -        if (max > DRIVER_LED_TOTAL) max = DRIVER_LED_TOTAL; +#    if defined(LED_MATRIX_SPLIT) +#        define LED_MATRIX_USE_LIMITS(min, max)                                                   \ +            uint8_t min = LED_MATRIX_LED_PROCESS_LIMIT * params->iter;                            \ +            uint8_t max = min + LED_MATRIX_LED_PROCESS_LIMIT;                                     \ +            if (max > DRIVER_LED_TOTAL) max = DRIVER_LED_TOTAL;                                   \ +            uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT;                                     \ +            if (is_keyboard_left() && (max > k_led_matrix_split[0])) max = k_led_matrix_split[0]; \ +            if (!(is_keyboard_left()) && (min < k_led_matrix_split[0])) min = k_led_matrix_split[0]; +#    else +#        define LED_MATRIX_USE_LIMITS(min, max)                        \ +            uint8_t min = LED_MATRIX_LED_PROCESS_LIMIT * params->iter; \ +            uint8_t max = min + LED_MATRIX_LED_PROCESS_LIMIT;          \ +            if (max > DRIVER_LED_TOTAL) max = DRIVER_LED_TOTAL; +#    endif  #else -#    define LED_MATRIX_USE_LIMITS(min, max) \ -        uint8_t min = 0;                    \ -        uint8_t max = DRIVER_LED_TOTAL; +#    if defined(LED_MATRIX_SPLIT) +#        define LED_MATRIX_USE_LIMITS(min, max)                                                   \ +            uint8_t       min                   = 0;                                              \ +            uint8_t       max                   = DRIVER_LED_TOTAL;                               \ +            const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT;                               \ +            if (is_keyboard_left() && (max > k_led_matrix_split[0])) max = k_led_matrix_split[0]; \ +            if (!(is_keyboard_left()) && (min < k_led_matrix_split[0])) min = k_led_matrix_split[0]; +#    else +#        define LED_MATRIX_USE_LIMITS(min, max) \ +            uint8_t min = 0;                    \ +            uint8_t max = DRIVER_LED_TOTAL; +#    endif  #endif  #define LED_MATRIX_TEST_LED_FLAGS() \ @@ -147,6 +166,18 @@ typedef struct {      void (*flush)(void);  } led_matrix_driver_t; +static inline bool led_matrix_check_finished_leds(uint8_t led_idx) { +#if defined(LED_MATRIX_SPLIT) +    if (is_keyboard_left()) { +        uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT; +        return led_idx < k_led_matrix_split[0]; +    } else +        return led_idx < DRIVER_LED_TOTAL; +#else +    return led_idx < DRIVER_LED_TOTAL; +#endif +} +  extern const led_matrix_driver_t led_matrix_driver;  extern led_eeconfig_t led_matrix_eeconfig; diff --git a/quantum/led_matrix/led_matrix_drivers.c b/quantum/led_matrix/led_matrix_drivers.c index 1d46b2c506..2157619a0b 100644 --- a/quantum/led_matrix/led_matrix_drivers.c +++ b/quantum/led_matrix/led_matrix_drivers.c @@ -26,128 +26,123 @@   */  #if defined(IS31FL3731) || defined(IS31FL3733) -  #    include "i2c_master.h"  static void init(void) {      i2c_init(); -#    ifdef IS31FL3731 -#        ifdef LED_DRIVER_ADDR_1 + +#    if defined(IS31FL3731)      IS31FL3731_init(LED_DRIVER_ADDR_1); -#        endif -#        ifdef LED_DRIVER_ADDR_2 +#        if defined(LED_DRIVER_ADDR_2)      IS31FL3731_init(LED_DRIVER_ADDR_2); -#        endif -#        ifdef LED_DRIVER_ADDR_3 +#            if defined(LED_DRIVER_ADDR_3)      IS31FL3731_init(LED_DRIVER_ADDR_3); -#        endif -#        ifdef LED_DRIVER_ADDR_4 +#                if defined(LED_DRIVER_ADDR_4)      IS31FL3731_init(LED_DRIVER_ADDR_4); -#        endif -#    else -#        ifdef LED_DRIVER_ADDR_1 -#            ifndef LED_DRIVER_SYNC_1 -#                define LED_DRIVER_SYNC_1 0 +#                endif  #            endif -    IS31FL3733_init(LED_DRIVER_ADDR_1, LED_DRIVER_SYNC_1);  #        endif -#        ifdef LED_DRIVER_ADDR_2 -#            ifndef LED_DRIVER_SYNC_2 + +#    elif defined(IS31FL3733) +#        if !defined(LED_DRIVER_SYNC_1) +#            define LED_DRIVER_SYNC_1 0 +#        endif +    IS31FL3733_init(LED_DRIVER_ADDR_1, LED_DRIVER_SYNC_1); +#        if defined(LED_DRIVER_ADDR_2) +#            if !defined(LED_DRIVER_SYNC_2)  #                define LED_DRIVER_SYNC_2 0  #            endif      IS31FL3733_init(LED_DRIVER_ADDR_2, LED_DRIVER_SYNC_2); -#        endif -#        ifdef LED_DRIVER_ADDR_3 -#            ifndef LED_DRIVER_SYNC_3 -#                define LED_DRIVER_SYNC_3 0 -#            endif +#            if defined(LED_DRIVER_ADDR_3) +#                if !defined(LED_DRIVER_SYNC_3) +#                    define LED_DRIVER_SYNC_3 0 +#                endif      IS31FL3733_init(LED_DRIVER_ADDR_3, LED_DRIVER_SYNC_3); -#        endif -#        ifdef LED_DRIVER_ADDR_4 -#            ifndef LED_DRIVER_SYNC_4 -#                define LED_DRIVER_SYNC_4 0 -#            endif +#                if defined(LED_DRIVER_ADDR_4) +#                    if !defined(LED_DRIVER_SYNC_4) +#                        define LED_DRIVER_SYNC_4 0 +#                    endif      IS31FL3733_init(LED_DRIVER_ADDR_4, LED_DRIVER_SYNC_4); +#                endif +#            endif  #        endif  #    endif      for (int index = 0; index < DRIVER_LED_TOTAL; index++) { -#    ifdef IS31FL3731 +#    if defined(IS31FL3731)          IS31FL3731_set_led_control_register(index, true); -#    else +#    elif defined(IS31FL3733)          IS31FL3733_set_led_control_register(index, true);  #    endif      } +  // This actually updates the LED drivers -#    ifdef IS31FL3731 -#        ifdef LED_DRIVER_ADDR_1 +#    if defined(IS31FL3731)      IS31FL3731_update_led_control_registers(LED_DRIVER_ADDR_1, 0); -#        endif -#        ifdef LED_DRIVER_ADDR_2 +#        if defined(LED_DRIVER_ADDR_2)      IS31FL3731_update_led_control_registers(LED_DRIVER_ADDR_2, 1); -#        endif -#        ifdef LED_DRIVER_ADDR_3 +#            if defined(LED_DRIVER_ADDR_3)      IS31FL3731_update_led_control_registers(LED_DRIVER_ADDR_3, 2); -#        endif -#        ifdef LED_DRIVER_ADDR_4 +#                if defined(LED_DRIVER_ADDR_4)      IS31FL3731_update_led_control_registers(LED_DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif -#    else -#        ifdef LED_DRIVER_ADDR_1 + +#    elif defined(IS31FL3733)      IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_1, 0); -#        endif -#        ifdef LED_DRIVER_ADDR_2 +#        if defined(LED_DRIVER_ADDR_2)      IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_2, 1); -#        endif -#        ifdef LED_DRIVER_ADDR_3 +#            if defined(LED_DRIVER_ADDR_3)      IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_3, 2); -#        endif -#        ifdef LED_DRIVER_ADDR_4 +#                if defined(LED_DRIVER_ADDR_4)      IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif  #    endif  } +#    if defined(IS31FL3731)  static void flush(void) { -#    ifdef IS31FL3731 -#        ifdef LED_DRIVER_ADDR_1      IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_1, 0); -#        endif -#        ifdef LED_DRIVER_ADDR_2 +#        if defined(LED_DRIVER_ADDR_2)      IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_2, 1); -#        endif -#        ifdef LED_DRIVER_ADDR_3 +#            if defined(LED_DRIVER_ADDR_3)      IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_3, 2); -#        endif -#        ifdef LED_DRIVER_ADDR_4 +#                if defined(LED_DRIVER_ADDR_4)      IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif -#    else -#        ifdef LED_DRIVER_ADDR_1 +} + +const led_matrix_driver_t led_matrix_driver = { +    .init          = init, +    .flush         = flush, +    .set_value     = IS31FL3731_set_value, +    .set_value_all = IS31FL3731_set_value_all, +}; + +#    elif defined(IS31FL3733) +static void flush(void) {      IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_1, 0); -#        endif -#        ifdef LED_DRIVER_ADDR_2 +#        if defined(LED_DRIVER_ADDR_2)      IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_2, 1); -#        endif -#        ifdef LED_DRIVER_ADDR_3 +#            if defined(LED_DRIVER_ADDR_3)      IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_3, 2); -#        endif -#        ifdef LED_DRIVER_ADDR_4 +#                if defined(LED_DRIVER_ADDR_4)      IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif -#    endif  }  const led_matrix_driver_t led_matrix_driver = { -    .init  = init, +    .init = init,      .flush = flush, -#    ifdef IS31FL3731 -    .set_value     = IS31FL3731_set_value, -    .set_value_all = IS31FL3731_set_value_all, -#    else      .set_value = IS31FL3733_set_value,      .set_value_all = IS31FL3733_set_value_all, -#    endif  }; - +#    endif  #endif diff --git a/quantum/main.c b/quantum/main.c index 2cbcd73d8f..3814d371c1 100644 --- a/quantum/main.c +++ b/quantum/main.c @@ -19,8 +19,29 @@  void platform_setup(void);  void protocol_setup(void); -void protocol_init(void); -void protocol_task(void); +void protocol_pre_init(void); +void protocol_post_init(void); +void protocol_pre_task(void); +void protocol_post_task(void); + +// Bodge as refactoring this area sucks.... +void protocol_init(void) __attribute__((weak)); +void protocol_init(void) { +    protocol_pre_init(); + +    keyboard_init(); + +    protocol_post_init(); +} + +void protocol_task(void) __attribute__((weak)); +void protocol_task(void) { +    protocol_pre_task(); + +    keyboard_task(); + +    protocol_post_task(); +}  /** \brief Main   * @@ -30,6 +51,7 @@ int main(void) __attribute__((weak));  int main(void) {      platform_setup();      protocol_setup(); +    keyboard_setup();      protocol_init(); diff --git a/quantum/matrix.c b/quantum/matrix.c index 33586c431b..483d518ecc 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -69,7 +69,7 @@ uint8_t thisHand, thatHand;  // user-defined overridable functions  __attribute__((weak)) void matrix_init_pins(void);  __attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row); -__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col); +__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col, matrix_row_t row_shifter);  #ifdef SPLIT_KEYBOARD  __attribute__((weak)) void matrix_slave_scan_kb(void) { matrix_slave_scan_user(); }  __attribute__((weak)) void matrix_slave_scan_user(void) {} @@ -113,10 +113,11 @@ __attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[]      // Start with a clear matrix row      matrix_row_t current_row_value = 0; -    for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { +    matrix_row_t row_shifter = MATRIX_ROW_SHIFTER; +    for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++, row_shifter <<= 1) {          pin_t pin = direct_pins[current_row][col_index];          if (pin != NO_PIN) { -            current_row_value |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index); +            current_row_value |= readPin(pin) ? 0 : row_shifter;          }      } @@ -169,11 +170,12 @@ __attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[]      matrix_output_select_delay();      // For each col... -    for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { +    matrix_row_t row_shifter = MATRIX_ROW_SHIFTER; +    for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++, row_shifter <<= 1) {          uint8_t pin_state = readMatrixPin(col_pins[col_index]);          // Populate the matrix row with the state of the col pin -        current_row_value |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index); +        current_row_value |= pin_state ? 0 : row_shifter;      }      // Unselect row @@ -217,7 +219,7 @@ __attribute__((weak)) void matrix_init_pins(void) {      }  } -__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { +__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col, matrix_row_t row_shifter) {      bool key_pressed = false;      // Select col @@ -231,11 +233,11 @@ __attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[]          // Check row pin state          if (readMatrixPin(row_pins[row_index]) == 0) {              // Pin LO, set col bit -            current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col); +            current_matrix[row_index] |= row_shifter;              key_pressed = true;          } else {              // Pin HI, clear col bit -            current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col); +            current_matrix[row_index] &= ~row_shifter;          }      } @@ -288,10 +290,8 @@ void matrix_init(void) {      matrix_init_pins();      // initialize matrix state: all keys off -    for (uint8_t i = 0; i < MATRIX_ROWS; i++) { -        raw_matrix[i] = 0; -        matrix[i]     = 0; -    } +    memset(matrix, 0, sizeof(matrix)); +    memset(raw_matrix, 0, sizeof(raw_matrix));      debounce_init(ROWS_PER_HAND); @@ -312,24 +312,22 @@ __attribute__((weak)) bool transport_master_if_connected(matrix_row_t master_mat  bool matrix_post_scan(void) {      bool changed = false;      if (is_keyboard_master()) { +        static bool  last_connected              = false;          matrix_row_t slave_matrix[ROWS_PER_HAND] = {0};          if (transport_master_if_connected(matrix + thisHand, slave_matrix)) { -            for (int i = 0; i < ROWS_PER_HAND; ++i) { -                if (matrix[thatHand + i] != slave_matrix[i]) { -                    matrix[thatHand + i] = slave_matrix[i]; -                    changed              = true; -                } -            } -        } else { -            // reset other half if disconnected -            for (int i = 0; i < ROWS_PER_HAND; ++i) { -                matrix[thatHand + i] = 0; -                slave_matrix[i]      = 0; -            } +            changed = memcmp(matrix + thatHand, slave_matrix, sizeof(slave_matrix)) != 0; +            last_connected = true; +        } else if (last_connected) { +            // reset other half when disconnected +            memset(slave_matrix, 0, sizeof(slave_matrix));              changed = true; + +            last_connected = false;          } +        if (changed) memcpy(matrix + thatHand, slave_matrix, sizeof(slave_matrix)); +          matrix_scan_quantum();      } else {          transport_slave(matrix + thatHand, matrix + thisHand); @@ -351,8 +349,9 @@ uint8_t matrix_scan(void) {      }  #elif (DIODE_DIRECTION == ROW2COL)      // Set col, read rows -    for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { -        matrix_read_rows_on_col(curr_matrix, current_col); +    matrix_row_t row_shifter = MATRIX_ROW_SHIFTER; +    for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++, row_shifter <<= 1) { +        matrix_read_rows_on_col(curr_matrix, current_col, row_shifter);      }  #endif diff --git a/quantum/mcu_selection.mk b/quantum/mcu_selection.mk deleted file mode 100644 index 3b86433a86..0000000000 --- a/quantum/mcu_selection.mk +++ /dev/null @@ -1,600 +0,0 @@ -MCU_ORIG := $(MCU) - -ifneq ($(findstring MKL26Z64, $(MCU)),) -  # Cortex version -  MCU = cortex-m0plus - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 6 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = KINETIS -  MCU_SERIES = KL2x - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= MKL26Z64 - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/ports/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= kl2x - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= PJRC_TEENSY_LC -endif - -ifneq ($(findstring MK20DX128, $(MCU)),) -  # Cortex version -  MCU = cortex-m4 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 7 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = KINETIS -  MCU_SERIES = K20x - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= MK20DX128 - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/ports/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= k20x5 - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= PJRC_TEENSY_3 -endif - -ifneq ($(findstring MK20DX256, $(MCU)),) -  # Cortex version -  MCU = cortex-m4 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 7 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = KINETIS -  MCU_SERIES = K20x - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= MK20DX256 - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/ports/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= k20x7 - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= PJRC_TEENSY_3_1 -endif - -ifneq ($(findstring MK66F18, $(MCU)),) -  # Cortex version -  MCU = cortex-m4 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 7 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = KINETIS -  MCU_SERIES = MK66F18 - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= MK66FX1M0 - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= MK66F18 - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= PJRC_TEENSY_3_6 -endif - -ifneq ($(findstring STM32F042, $(MCU)),) -  # Cortex version -  MCU = cortex-m0 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 6 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = STM32 -  MCU_SERIES = STM32F0xx - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= STM32F042x6 - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= stm32f0xx - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= GENERIC_STM32_F042X6 - -  USE_FPU ?= no - -  # UF2 settings -  UF2_FAMILY ?= STM32F0 -endif - -ifneq ($(findstring STM32F072, $(MCU)),) -  # Cortex version -  MCU = cortex-m0 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 6 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = STM32 -  MCU_SERIES = STM32F0xx - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= STM32F072xB - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= stm32f0xx - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= GENERIC_STM32_F072XB - -  USE_FPU ?= no - -  # UF2 settings -  UF2_FAMILY ?= STM32F0 -endif - -ifneq ($(findstring STM32F103, $(MCU)),) -  # Cortex version -  MCU = cortex-m3 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 7 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = STM32 -  MCU_SERIES = STM32F1xx - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= STM32F103x8 - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= stm32f1xx - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= GENERIC_STM32_F103 - -  USE_FPU ?= no - -  # UF2 settings -  UF2_FAMILY ?= STM32F1 -endif - -ifneq ($(findstring STM32F303, $(MCU)),) -  # Cortex version -  MCU = cortex-m4 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 7 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = STM32 -  MCU_SERIES = STM32F3xx - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= STM32F303xC - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= stm32f3xx - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= GENERIC_STM32_F303XC - -  USE_FPU ?= yes - -  # UF2 settings -  UF2_FAMILY ?= STM32F3 -endif - -ifneq ($(findstring STM32F401, $(MCU)),) -  # Cortex version -  MCU = cortex-m4 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 7 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = STM32 -  MCU_SERIES = STM32F4xx - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  ifeq ($(strip $(BOOTLOADER)), tinyuf2) -    MCU_LDSCRIPT ?= STM32F401xC_tinyuf2 -    FIRMWARE_FORMAT ?= uf2 -  else -    MCU_LDSCRIPT ?= STM32F401xC -  endif - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= stm32f4xx - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= BLACKPILL_STM32_F401 - -  USE_FPU ?= yes - -  # UF2 settings -  UF2_FAMILY ?= STM32F4 -endif - -ifneq ($(findstring STM32F407, $(MCU)),) -  # Cortex version -  MCU = cortex-m4 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 7 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = STM32 -  MCU_SERIES = STM32F4xx - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= STM32F407xE - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= stm32f4xx - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= GENERIC_STM32_F407XE - -  USE_FPU ?= yes - -  # UF2 settings -  UF2_FAMILY ?= STM32F4 -endif - -ifneq ($(findstring STM32F411, $(MCU)),) -  # Cortex version -  MCU = cortex-m4 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 7 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = STM32 -  MCU_SERIES = STM32F4xx - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  ifeq ($(strip $(BOOTLOADER)), tinyuf2) -    MCU_LDSCRIPT ?= STM32F411xE_tinyuf2 -    FIRMWARE_FORMAT ?= uf2 -  else -    MCU_LDSCRIPT ?= STM32F411xE -  endif - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= stm32f4xx - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= BLACKPILL_STM32_F411 - -  USE_FPU ?= yes - -  # UF2 settings -  UF2_FAMILY ?= STM32F4 -endif - -ifneq ($(findstring STM32F446, $(MCU)),) -  # Cortex version -  MCU = cortex-m4 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 7 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = STM32 -  MCU_SERIES = STM32F4xx - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= STM32F446xE - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= stm32f4xx - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= GENERIC_STM32_F446XE - -  USE_FPU ?= yes -endif - -ifneq ($(findstring STM32G431, $(MCU)),) -  # Cortex version -  MCU = cortex-m4 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 7 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = STM32 -  MCU_SERIES = STM32G4xx - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= STM32G431xB - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= stm32g4xx - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= GENERIC_STM32_G431XB - -  USE_FPU ?= yes - -  # UF2 settings -  UF2_FAMILY ?= STM32G4 -endif - -ifneq ($(findstring STM32G474, $(MCU)),) -  # Cortex version -  MCU = cortex-m4 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 7 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = STM32 -  MCU_SERIES = STM32G4xx - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= STM32G474xE - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= stm32g4xx - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= GENERIC_STM32_G474XE - -  USE_FPU ?= yes - -  # UF2 settings -  UF2_FAMILY ?= STM32G4 -endif - -ifneq (,$(filter $(MCU),STM32L433 STM32L443)) -  # Cortex version -  MCU = cortex-m4 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 7 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = STM32 -  MCU_SERIES = STM32L4xx - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= STM32L432xC - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= stm32l4xx - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= GENERIC_STM32_L433XC - -  PLATFORM_NAME ?= platform_l432 - -  USE_FPU ?= yes - -  # UF2 settings -  UF2_FAMILY ?= STM32L4 -endif - -ifneq (,$(filter $(MCU),STM32L412 STM32L422)) -  # Cortex version -  MCU = cortex-m4 - -  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 -  ARMV = 7 - -  ## chip/board settings -  # - the next two should match the directories in -  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) -  MCU_FAMILY = STM32 -  MCU_SERIES = STM32L4xx - -  # Linker script to use -  # - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/ -  #   or <keyboard_dir>/ld/ -  MCU_LDSCRIPT ?= STM32L412xB - -  # Startup code to use -  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ -  MCU_STARTUP ?= stm32l4xx - -  # Board: it should exist either in <chibios>/os/hal/boards/, -  # <keyboard_dir>/boards/, or drivers/boards/ -  BOARD ?= GENERIC_STM32_L412XB - -  PLATFORM_NAME ?= platform_l432 - -  USE_FPU ?= yes - -  # UF2 settings -  UF2_FAMILY ?= STM32L4 -endif - -ifneq (,$(filter $(MCU),at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647 at90usb1286 at90usb1287)) -  PROTOCOL = LUFA - -  # Processor frequency. -  #     This will define a symbol, F_CPU, in all source code files equal to the -  #     processor frequency in Hz. You can then use this symbol in your source code to -  #     calculate timings. Do NOT tack on a 'UL' at the end, this will be done -  #     automatically to create a 32-bit value in your source code. -  # -  #     This will be an integer division of F_USB below, as it is sourced by -  #     F_USB after it has run through any CPU prescalers. Note that this value -  #     does not *change* the processor frequency - it should merely be updated to -  #     reflect the processor speed set externally so that the code can use accurate -  #     software delays. -  F_CPU ?= 16000000 - -  # LUFA specific -  # -  # Target architecture (see library "Board Types" documentation). -  ARCH = AVR8 - -  # Input clock frequency. -  #     This will define a symbol, F_USB, in all source code files equal to the -  #     input clock frequency (before any prescaling is performed) in Hz. This value may -  #     differ from F_CPU if prescaling is used on the latter, and is required as the -  #     raw input clock is fed directly to the PLL sections of the AVR for high speed -  #     clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' -  #     at the end, this will be done automatically to create a 32-bit value in your -  #     source code. -  # -  #     If no clock division is performed on the input clock inside the AVR (via the -  #     CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. -  F_USB ?= $(F_CPU) - -  # Interrupt driven control endpoint task -  ifeq (,$(filter $(NO_INTERRUPT_CONTROL_ENDPOINT),yes)) -    OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT -  endif -  ifneq (,$(filter $(MCU),at90usb162 atmega16u2 atmega32u2)) -    NO_I2C = yes -  endif -endif - -ifneq (,$(filter $(MCU),atmega32a)) -  # MCU name for avrdude -  AVRDUDE_MCU = m32 - -  PROTOCOL = VUSB - -  # Processor frequency. -  #     This will define a symbol, F_CPU, in all source code files equal to the -  #     processor frequency in Hz. You can then use this symbol in your source code to -  #     calculate timings. Do NOT tack on a 'UL' at the end, this will be done -  #     automatically to create a 32-bit value in your source code. -  F_CPU ?= 12000000 -endif - -ifneq (,$(filter $(MCU),atmega328p)) -  # MCU name for avrdude -  AVRDUDE_MCU = m328p - -  PROTOCOL = VUSB - -  # Processor frequency. -  #     This will define a symbol, F_CPU, in all source code files equal to the -  #     processor frequency in Hz. You can then use this symbol in your source code to -  #     calculate timings. Do NOT tack on a 'UL' at the end, this will be done -  #     automatically to create a 32-bit value in your source code. -  F_CPU ?= 16000000 -endif - -ifneq (,$(filter $(MCU),atmega328)) -  # MCU name for avrdude -  AVRDUDE_MCU = m328 - -  PROTOCOL = VUSB - -  # Processor frequency. -  #     This will define a symbol, F_CPU, in all source code files equal to the -  #     processor frequency in Hz. You can then use this symbol in your source code to -  #     calculate timings. Do NOT tack on a 'UL' at the end, this will be done -  #     automatically to create a 32-bit value in your source code. -  F_CPU ?= 16000000 -endif - -ifneq (,$(filter $(MCU),attiny85)) -  PROTOCOL = VUSB - -  # Processor frequency. -  #     This will define a symbol, F_CPU, in all source code files equal to the -  #     processor frequency in Hz. You can then use this symbol in your source code to -  #     calculate timings. Do NOT tack on a 'UL' at the end, this will be done -  #     automatically to create a 32-bit value in your source code. -  F_CPU ?= 16500000 -endif diff --git a/quantum/process_keycode/process_auto_shift.c b/quantum/process_keycode/process_auto_shift.c index 51b0efdb47..02af5174f7 100644 --- a/quantum/process_keycode/process_auto_shift.c +++ b/quantum/process_keycode/process_auto_shift.c @@ -21,6 +21,12 @@  #    include "process_auto_shift.h" +#ifndef AUTO_SHIFT_DISABLED_AT_STARTUP +#   define AUTO_SHIFT_STARTUP_STATE true    /* enabled */ +#else +#   define AUTO_SHIFT_STARTUP_STATE false   /* disabled */ +#endif +  static uint16_t autoshift_time    = 0;  static uint16_t autoshift_timeout = AUTO_SHIFT_TIMEOUT;  static uint16_t autoshift_lastkey = KC_NO; @@ -34,7 +40,7 @@ static struct {      bool in_progress : 1;      // Whether the auto-shifted keypress has been registered.      bool holding_shift : 1; -} autoshift_flags = {true, false, false, false}; +} autoshift_flags = {AUTO_SHIFT_STARTUP_STATE, false, false, false};  /** \brief Record the press of an autoshiftable key   * @@ -61,7 +67,7 @@ static bool autoshift_press(uint16_t keycode, uint16_t now, keyrecord_t *record)                  register_code(autoshift_lastkey);              } else {                  // Simulate pressing the shift key. -                add_weak_mods(MOD_BIT(KC_LSFT)); +                add_weak_mods(MOD_BIT(KC_LEFT_SHIFT));                  register_code(autoshift_lastkey);              }              return false; @@ -102,7 +108,7 @@ static void autoshift_end(uint16_t keycode, uint16_t now, bool matrix_trigger) {              autoshift_flags.lastshifted = false;          } else {              // Simulate pressing the shift key. -            add_weak_mods(MOD_BIT(KC_LSFT)); +            add_weak_mods(MOD_BIT(KC_LEFT_SHIFT));              register_code(autoshift_lastkey);              autoshift_flags.lastshifted = true;  #    if defined(AUTO_SHIFT_REPEAT) && !defined(AUTO_SHIFT_NO_AUTO_REPEAT) @@ -117,7 +123,7 @@ static void autoshift_end(uint16_t keycode, uint16_t now, bool matrix_trigger) {          wait_ms(TAP_CODE_DELAY);  #    endif          unregister_code(autoshift_lastkey); -        del_weak_mods(MOD_BIT(KC_LSFT)); +        del_weak_mods(MOD_BIT(KC_LEFT_SHIFT));      } else {          // Release after keyrepeat.          unregister_code(keycode); @@ -125,7 +131,7 @@ static void autoshift_end(uint16_t keycode, uint16_t now, bool matrix_trigger) {              // This will only fire when the key was the last auto-shiftable              // pressed. That prevents aaaaBBBB then releasing a from unshifting              // later Bs (if B wasn't auto-shiftable). -            del_weak_mods(MOD_BIT(KC_LSFT)); +            del_weak_mods(MOD_BIT(KC_LEFT_SHIFT));          }      }      send_keyboard_report();  // del_weak_mods doesn't send one. @@ -151,14 +157,14 @@ void autoshift_matrix_scan(void) {  void autoshift_toggle(void) {      autoshift_flags.enabled = !autoshift_flags.enabled; -    del_weak_mods(MOD_BIT(KC_LSFT)); +    del_weak_mods(MOD_BIT(KC_LEFT_SHIFT));  }  void autoshift_enable(void) { autoshift_flags.enabled = true; }  void autoshift_disable(void) {      autoshift_flags.enabled = false; -    del_weak_mods(MOD_BIT(KC_LSFT)); +    del_weak_mods(MOD_BIT(KC_LEFT_SHIFT));  }  #    ifndef AUTO_SHIFT_NO_SETUP @@ -189,7 +195,7 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {              autoshift_end(KC_NO, now, false);          }          // For pressing another key while keyrepeating shifted autoshift. -        del_weak_mods(MOD_BIT(KC_LSFT)); +        del_weak_mods(MOD_BIT(KC_LEFT_SHIFT));          switch (keycode) {              case KC_ASTG: @@ -238,7 +244,7 @@ __attribute__((weak)) bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *r  #    ifndef NO_AUTO_SHIFT_SPECIAL          case KC_TAB:          case KC_MINUS ... KC_SLASH: -        case KC_NONUS_BSLASH: +        case KC_NONUS_BACKSLASH:  #    endif              return true;      } diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c index e8661839c7..a050161edf 100644 --- a/quantum/process_keycode/process_combo.c +++ b/quantum/process_keycode/process_combo.c @@ -18,10 +18,9 @@  #include "process_combo.h"  #include "action_tapping.h" -  #ifdef COMBO_COUNT -__attribute__((weak)) combo_t  key_combos[COMBO_COUNT]; -uint16_t COMBO_LEN = COMBO_COUNT; +__attribute__((weak)) combo_t key_combos[COMBO_COUNT]; +uint16_t                      COMBO_LEN = COMBO_COUNT;  #else  extern combo_t  key_combos[];  extern uint16_t COMBO_LEN; @@ -46,64 +45,86 @@ __attribute__((weak)) bool process_combo_key_release(uint16_t combo_index, combo  #endif  #ifndef COMBO_NO_TIMER -static uint16_t timer                 = 0; +static uint16_t timer = 0;  #endif -static bool     b_combo_enable        = true;  // defaults to enabled -static uint16_t longest_term          = 0; +static bool     b_combo_enable = true;  // defaults to enabled +static uint16_t longest_term   = 0;  typedef struct {      keyrecord_t record; -    uint16_t combo_index; -    uint16_t keycode; +    uint16_t    combo_index; +    uint16_t    keycode;  } queued_record_t; -static uint8_t key_buffer_size = 0; +static uint8_t         key_buffer_size = 0;  static queued_record_t key_buffer[COMBO_KEY_BUFFER_LENGTH];  typedef struct {      uint16_t combo_index;  } queued_combo_t; -static uint8_t combo_buffer_write= 0; -static uint8_t combo_buffer_read = 0; +static uint8_t        combo_buffer_write = 0; +static uint8_t        combo_buffer_read  = 0;  static queued_combo_t combo_buffer[COMBO_BUFFER_LENGTH];  #define INCREMENT_MOD(i) i = (i + 1) % COMBO_BUFFER_LENGTH -#define COMBO_KEY_POS ((keypos_t){.col=254, .row=254}) - +#define COMBO_KEY_POS ((keypos_t){.col = 254, .row = 254})  #ifndef EXTRA_SHORT_COMBOS  /* flags are their own elements in combo_t struct. */ -#    define COMBO_ACTIVE(combo)   (combo->active) +#    define COMBO_ACTIVE(combo) (combo->active)  #    define COMBO_DISABLED(combo) (combo->disabled) -#    define COMBO_STATE(combo)    (combo->state) - -#    define ACTIVATE_COMBO(combo)    do {combo->active = true;}while(0) -#    define DEACTIVATE_COMBO(combo)  do {combo->active = false;}while(0) -#    define DISABLE_COMBO(combo)     do {combo->disabled = true;}while(0) -#    define RESET_COMBO_STATE(combo) do { \ -    combo->disabled = false; \ -    combo->state = 0; \ -}while(0) +#    define COMBO_STATE(combo) (combo->state) + +#    define ACTIVATE_COMBO(combo) \ +        do {                      \ +            combo->active = true; \ +        } while (0) +#    define DEACTIVATE_COMBO(combo) \ +        do {                        \ +            combo->active = false;  \ +        } while (0) +#    define DISABLE_COMBO(combo)    \ +        do {                        \ +            combo->disabled = true; \ +        } while (0) +#    define RESET_COMBO_STATE(combo) \ +        do {                         \ +            combo->disabled = false; \ +            combo->state    = 0;     \ +        } while (0)  #else  /* flags are at the two high bits of state. */ -#    define COMBO_ACTIVE(combo)   (combo->state & 0x80) +#    define COMBO_ACTIVE(combo) (combo->state & 0x80)  #    define COMBO_DISABLED(combo) (combo->state & 0x40) -#    define COMBO_STATE(combo)    (combo->state & 0x3F) - -#    define ACTIVATE_COMBO(combo)    do {combo->state |= 0x80;}while(0) -#    define DEACTIVATE_COMBO(combo)  do {combo->state &= ~0x80;}while(0) -#    define DISABLE_COMBO(combo)     do {combo->state |= 0x40;}while(0) -#    define RESET_COMBO_STATE(combo) do {combo->state &= ~0x7F;}while(0) +#    define COMBO_STATE(combo) (combo->state & 0x3F) + +#    define ACTIVATE_COMBO(combo) \ +        do {                      \ +            combo->state |= 0x80; \ +        } while (0) +#    define DEACTIVATE_COMBO(combo) \ +        do {                        \ +            combo->state &= ~0x80;  \ +        } while (0) +#    define DISABLE_COMBO(combo)  \ +        do {                      \ +            combo->state |= 0x40; \ +        } while (0) +#    define RESET_COMBO_STATE(combo) \ +        do {                         \ +            combo->state &= ~0x7F;   \ +        } while (0)  #endif  static inline void release_combo(uint16_t combo_index, combo_t *combo) {      if (combo->keycode) {          keyrecord_t record = { -            .event = { -                .key = COMBO_KEY_POS, -                .time = timer_read()|1, -                .pressed = false, -            }, +            .event = +                { +                    .key     = COMBO_KEY_POS, +                    .time    = timer_read() | 1, +                    .pressed = false, +                },              .keycode = combo->keycode,          };  #ifndef NO_ACTION_TAPPING @@ -123,18 +144,17 @@ static inline bool _get_combo_must_hold(uint16_t combo_index, combo_t *combo) {  #elif defined(COMBO_MUST_HOLD_PER_COMBO)      return get_combo_must_hold(combo_index, combo);  #elif defined(COMBO_MUST_HOLD_MODS) -    return (KEYCODE_IS_MOD(combo->keycode) || -            (combo->keycode >= QK_MOMENTARY && combo->keycode <= QK_MOMENTARY_MAX)); +    return (KEYCODE_IS_MOD(combo->keycode) || (combo->keycode >= QK_MOMENTARY && combo->keycode <= QK_MOMENTARY_MAX));  #endif      return false;  } -static inline uint16_t _get_wait_time(uint16_t combo_index, combo_t *combo ) { +static inline uint16_t _get_wait_time(uint16_t combo_index, combo_t *combo) {      if (_get_combo_must_hold(combo_index, combo)  #ifdef COMBO_MUST_TAP_PER_COMBO -            || get_combo_must_tap(combo_index, combo) +        || get_combo_must_tap(combo_index, combo)  #endif -       ) { +    ) {          if (longest_term < COMBO_HOLD_TERM) {              return COMBO_HOLD_TERM;          } @@ -144,9 +164,8 @@ static inline uint16_t _get_wait_time(uint16_t combo_index, combo_t *combo ) {  }  static inline uint16_t _get_combo_term(uint16_t combo_index, combo_t *combo) { -  #if defined(COMBO_TERM_PER_COMBO) -        return get_combo_term(combo_index, combo); +    return get_combo_term(combo_index, combo);  #endif      return COMBO_TERM; @@ -154,7 +173,7 @@ static inline uint16_t _get_combo_term(uint16_t combo_index, combo_t *combo) {  void clear_combos(void) {      uint16_t index = 0; -    longest_term = 0; +    longest_term   = 0;      for (index = 0; index < COMBO_LEN; ++index) {          combo_t *combo = &key_combos[index];          if (!COMBO_ACTIVE(combo)) { @@ -175,7 +194,7 @@ static inline void dump_key_buffer(void) {          key_buffer_next = key_buffer_i + 1;          queued_record_t *qrecord = &key_buffer[key_buffer_i]; -        keyrecord_t *record = &qrecord->record; +        keyrecord_t *    record  = &qrecord->record;          if (IS_NOEVENT(record->event)) {              continue; @@ -185,9 +204,9 @@ static inline void dump_key_buffer(void) {              process_combo_event(qrecord->combo_index, true);          } else {  #ifndef NO_ACTION_TAPPING -        action_tapping_process(*record); +            action_tapping_process(*record);  #else -        process_record(record); +            process_record(record);  #endif          }          record->event.time = 0; @@ -242,7 +261,9 @@ void apply_combo(uint16_t combo_index, combo_t *combo) {      /* Apply combo's result keycode to the last chord key of the combo and       * disable the other keys. */ -    if (COMBO_DISABLED(combo)) { return; } +    if (COMBO_DISABLED(combo)) { +        return; +    }      // state to check against so we find the last key of the combo from the buffer  #if defined(EXTRA_EXTRA_LONG_COMBOS) @@ -254,12 +275,11 @@ void apply_combo(uint16_t combo_index, combo_t *combo) {  #endif      for (uint8_t key_buffer_i = 0; key_buffer_i < key_buffer_size; key_buffer_i++) { -          queued_record_t *qrecord = &key_buffer[key_buffer_i]; -        keyrecord_t *record = &qrecord->record; -        uint16_t keycode = qrecord->keycode; +        keyrecord_t *    record  = &qrecord->record; +        uint16_t         keycode = qrecord->keycode; -        uint8_t key_count = 0; +        uint8_t  key_count = 0;          uint16_t key_index = -1;          _find_key_index_and_count(combo->keys, keycode, &key_index, &key_count); @@ -271,7 +291,7 @@ void apply_combo(uint16_t combo_index, combo_t *combo) {          KEY_STATE_DOWN(state, key_index);          if (ALL_COMBO_KEYS_ARE_DOWN(state, key_count)) {              // this in the end executes the combo when the key_buffer is dumped. -            record->keycode = combo->keycode; +            record->keycode   = combo->keycode;              record->event.key = COMBO_KEY_POS;              qrecord->combo_index = combo_index; @@ -283,19 +303,15 @@ void apply_combo(uint16_t combo_index, combo_t *combo) {              // by making it a TICK event.              record->event.time = 0;          } -      }      drop_combo_from_buffer(combo_index);  }  static inline void apply_combos(void) {      // Apply all buffered normal combos. -    for (uint8_t i = combo_buffer_read; -            i != combo_buffer_write; -            INCREMENT_MOD(i)) { - +    for (uint8_t i = combo_buffer_read; i != combo_buffer_write; INCREMENT_MOD(i)) {          queued_combo_t *buffered_combo = &combo_buffer[i]; -        combo_t *combo = &key_combos[buffered_combo->combo_index]; +        combo_t *       combo          = &key_combos[buffered_combo->combo_index];  #ifdef COMBO_MUST_TAP_PER_COMBO          if (get_combo_must_tap(buffered_combo->combo_index, combo)) { @@ -310,15 +326,15 @@ static inline void apply_combos(void) {      clear_combos();  } -combo_t* overlaps(combo_t *combo1, combo_t *combo2) { +combo_t *overlaps(combo_t *combo1, combo_t *combo2) {      /* Checks if the combos overlap and returns the combo that should be       * dropped from the combo buffer.       * The combo that has less keys will be dropped. If they have the same       * amount of keys, drop combo1. */ -    uint8_t idx1 = 0, idx2 = 0; +    uint8_t  idx1 = 0, idx2 = 0;      uint16_t key1, key2; -    bool overlaps = false; +    bool     overlaps = false;      while ((key1 = pgm_read_word(&combo1->keys[idx1])) != COMBO_END) {          idx2 = 0; @@ -335,7 +351,7 @@ combo_t* overlaps(combo_t *combo1, combo_t *combo2) {  }  static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record, uint16_t combo_index) { -    uint8_t key_count = 0; +    uint8_t  key_count = 0;      uint16_t key_index = -1;      _find_key_index_and_count(combo->keys, keycode, &key_index, &key_count); @@ -369,12 +385,9 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *                  // disable readied combos that overlap with this combo                  combo_t *drop = NULL; -                for (uint8_t combo_buffer_i = combo_buffer_read; -                        combo_buffer_i != combo_buffer_write; -                        INCREMENT_MOD(combo_buffer_i)) { - -                    queued_combo_t *qcombo = &combo_buffer[combo_buffer_i]; -                    combo_t *buffered_combo = &key_combos[qcombo->combo_index]; +                for (uint8_t combo_buffer_i = combo_buffer_read; combo_buffer_i != combo_buffer_write; INCREMENT_MOD(combo_buffer_i)) { +                    queued_combo_t *qcombo         = &combo_buffer[combo_buffer_i]; +                    combo_t *       buffered_combo = &key_combos[qcombo->combo_index];                      if ((drop = overlaps(buffered_combo, combo))) {                          DISABLE_COMBO(drop); @@ -387,21 +400,19 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *                              INCREMENT_MOD(combo_buffer_read);                          }                      } -                  }                  if (drop != combo) {                      // save this combo to buffer                      combo_buffer[combo_buffer_write] = (queued_combo_t){ -                        .combo_index=combo_index, +                        .combo_index = combo_index,                      };                      INCREMENT_MOD(combo_buffer_write);                      // get possible longer waiting time for tap-/hold-only combos.                      longest_term = _get_wait_time(combo_index, combo);                  } -            } // if timer elapsed end - +            }  // if timer elapsed end          }      } else {          // chord releases @@ -416,7 +427,7 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *              else if (get_combo_must_tap(combo_index, combo)) {                  // immediately apply tap-only combo                  apply_combo(combo_index, combo); -                apply_combos(); // also apply other prepared combos and dump key buffer +                apply_combos();  // also apply other prepared combos and dump key buffer  #    ifdef COMBO_PROCESS_KEY_RELEASE                  if (process_combo_key_release(combo_index, combo, key_index, keycode)) {                      release_combo(combo_index, combo); @@ -424,10 +435,7 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *  #    endif              }  #endif -        } else if (COMBO_ACTIVE(combo) -                && ONLY_ONE_KEY_IS_DOWN(COMBO_STATE(combo)) -                && KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index) -                ) { +        } else if (COMBO_ACTIVE(combo) && ONLY_ONE_KEY_IS_DOWN(COMBO_STATE(combo)) && KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index)) {              /* last key released */              release_combo(combo_index, combo);              key_is_part_of_combo = true; @@ -435,9 +443,7 @@ static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *  #ifdef COMBO_PROCESS_KEY_RELEASE              process_combo_key_release(combo_index, combo, key_index, keycode);  #endif -        } else if (COMBO_ACTIVE(combo) -                && KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index) -                ) { +        } else if (COMBO_ACTIVE(combo) && KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index)) {              /* first or middle key released */              key_is_part_of_combo = true; @@ -489,21 +495,21 @@ bool process_combo(uint16_t keycode, keyrecord_t *record) {      if (record->event.pressed && is_combo_key) {  #ifndef COMBO_NO_TIMER -#   ifdef COMBO_STRICT_TIMER +#    ifdef COMBO_STRICT_TIMER          if (!timer) {              // timer is set only on the first key              timer = timer_read();          } -#   else +#    else          timer = timer_read(); -#   endif +#    endif  #endif          if (key_buffer_size < COMBO_KEY_BUFFER_LENGTH) {              key_buffer[key_buffer_size++] = (queued_record_t){ -                .record = *record, -                .keycode = keycode, -                .combo_index = -1, // this will be set when applying combos +                .record      = *record, +                .keycode     = keycode, +                .combo_index = -1,  // this will be set when applying combos              };          }      } else { @@ -532,7 +538,7 @@ void combo_task(void) {          if (combo_buffer_read != combo_buffer_write) {              apply_combos();              longest_term = 0; -            timer = 0; +            timer        = 0;          } else {              dump_key_buffer();              timer = 0; @@ -546,9 +552,9 @@ void combo_enable(void) { b_combo_enable = true; }  void combo_disable(void) {  #ifndef COMBO_NO_TIMER -    timer                      = 0; +    timer = 0;  #endif -    b_combo_enable = false; +    b_combo_enable    = false;      combo_buffer_read = combo_buffer_write;      clear_combos();      dump_key_buffer(); diff --git a/quantum/process_keycode/process_combo.h b/quantum/process_keycode/process_combo.h index 43c36d79e6..4c4e574e34 100644 --- a/quantum/process_keycode/process_combo.h +++ b/quantum/process_keycode/process_combo.h @@ -43,8 +43,8 @@ typedef struct {  #ifdef EXTRA_SHORT_COMBOS      uint8_t state;  #else -    bool disabled; -    bool active; +    bool     disabled; +    bool     active;  #    if defined(EXTRA_EXTRA_LONG_COMBOS)      uint32_t state;  #    elif defined(EXTRA_LONG_COMBOS) diff --git a/quantum/process_keycode/process_haptic.c b/quantum/process_keycode/process_haptic.c index 64d455d009..85b2ffcddd 100644 --- a/quantum/process_keycode/process_haptic.c +++ b/quantum/process_keycode/process_haptic.c @@ -17,6 +17,7 @@  #include "process_haptic.h"  #include "quantum_keycodes.h"  #include "action_tapping.h" +#include "usb_device_state.h"  __attribute__((weak)) bool get_haptic_enabled_key(uint16_t keycode, keyrecord_t *record) {      switch (keycode) { @@ -30,8 +31,9 @@ __attribute__((weak)) bool get_haptic_enabled_key(uint16_t keycode, keyrecord_t          case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:              if (record->tap.count == 0) return false;              break; -        case KC_LCTRL ... KC_RGUI: +        case KC_LEFT_CTRL ... KC_RIGHT_GUI:          case QK_MOMENTARY ... QK_MOMENTARY_MAX: +        case QK_LAYER_MOD ... QK_LAYER_MOD_MAX:  #endif  #ifdef NO_HAPTIC_FN          case KC_FN0 ... KC_FN31: @@ -42,34 +44,34 @@ __attribute__((weak)) bool get_haptic_enabled_key(uint16_t keycode, keyrecord_t  #ifdef NO_HAPTIC_PUNCTUATION          case KC_ENTER:          case KC_ESCAPE: -        case KC_BSPACE: +        case KC_BACKSPACE:          case KC_SPACE:          case KC_MINUS:          case KC_EQUAL: -        case KC_LBRACKET: -        case KC_RBRACKET: -        case KC_BSLASH: +        case KC_LEFT_BRACKET: +        case KC_RIGHT_BRACKET: +        case KC_BACKSLASH:          case KC_NONUS_HASH: -        case KC_SCOLON: +        case KC_SEMICOLON:          case KC_QUOTE:          case KC_GRAVE:          case KC_COMMA:          case KC_SLASH:          case KC_DOT: -        case KC_NONUS_BSLASH: +        case KC_NONUS_BACKSLASH:  #endif  #ifdef NO_HAPTIC_LOCKKEYS -        case KC_CAPSLOCK: -        case KC_SCROLLLOCK: -        case KC_NUMLOCK: +        case KC_CAPS_LOCK: +        case KC_SCROLL_LOCK: +        case KC_NUM_LOCK:  #endif  #ifdef NO_HAPTIC_NAV -        case KC_PSCREEN: +        case KC_PRINT_SCREEN:          case KC_PAUSE:          case KC_INSERT:          case KC_DELETE: -        case KC_PGDOWN: -        case KC_PGUP: +        case KC_PAGE_DOWN: +        case KC_PAGE_UP:          case KC_LEFT:          case KC_UP:          case KC_RIGHT: @@ -130,7 +132,7 @@ bool process_haptic(uint16_t keycode, keyrecord_t *record) {          }      } -    if (haptic_get_enable()) { +    if (haptic_get_enable() && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED))) {          if (record->event.pressed) {              // keypress              if (haptic_get_feedback() < 2 && get_haptic_enabled_key(keycode, record)) { diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c index 2beccbd8f9..6822c5e289 100644 --- a/quantum/process_keycode/process_music.c +++ b/quantum/process_keycode/process_music.c @@ -146,7 +146,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {      if (music_activated || midi_activated) {          if (record->event.pressed) { -            if (keycode == KC_LCTL) {  // Start recording +            if (keycode == KC_LEFT_CTRL) {  // Start recording                  music_all_notes_off();                  music_sequence_recording = true;                  music_sequence_recorded  = false; @@ -155,7 +155,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {                  return false;              } -            if (keycode == KC_LALT) {  // Stop recording/playing +            if (keycode == KC_LEFT_ALT) {  // Stop recording/playing                  music_all_notes_off();                  if (music_sequence_recording) {  // was recording                      music_sequence_recorded = true; @@ -165,7 +165,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {                  return false;              } -            if (keycode == KC_LGUI && music_sequence_recorded) {  // Start playing +            if (keycode == KC_LEFT_GUI && music_sequence_recorded) {  // Start playing                  music_all_notes_off();                  music_sequence_recording = false;                  music_sequence_playing   = true; diff --git a/quantum/process_keycode/process_printer.c b/quantum/process_keycode/process_printer.c index 7c5e4169a6..82528cc680 100644 --- a/quantum/process_keycode/process_printer.c +++ b/quantum/process_keycode/process_printer.c @@ -31,7 +31,7 @@ uint8_t shifted_numbers[10] = {0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0  // uint8_t keycode_to_ascii[0xFF][2]; -// keycode_to_ascii[KC_MINS] = {0x2D, 0x5F}; +// keycode_to_ascii[KC_MINUS] = {0x2D, 0x5F};  void print_char(char c) {      USB_Disable(); @@ -90,8 +90,8 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {              case KC_PIPE:              case KC_TILD:                  keycode &= 0xFF; -            case KC_LSFT: -            case KC_RSFT: +            case KC_LEFT_SHIFT: +            case KC_RIGHT_SHIFT:                  if (record->event.pressed) {                      character_shift++;                  } else { @@ -107,13 +107,13 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                      print_box_string("This is a line of text!");                  }                  return false; -            case KC_ESC: +            case KC_ESCAPE:                  if (record->event.pressed) {                      print_char(0x1B);                  }                  return false;                  break; -            case KC_SPC: +            case KC_SPACE:                  if (record->event.pressed) {                      print_char(0x20);                  } @@ -139,7 +139,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_ENT: +            case KC_ENTER:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x0C); @@ -149,7 +149,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_BSPC: +            case KC_BACKSPACE:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x18); @@ -169,7 +169,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_COMM: +            case KC_COMMA:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x3C); @@ -179,7 +179,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_SLSH: +            case KC_SLASH:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x3F); @@ -189,7 +189,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_QUOT: +            case KC_QUOTE:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x22); @@ -199,7 +199,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_GRV: +            case KC_GRAVE:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x7E); @@ -209,7 +209,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_MINS: +            case KC_MINUS:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x5F); @@ -219,7 +219,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_EQL: +            case KC_EQUAL:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x2B); @@ -229,7 +229,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_LBRC: +            case KC_LEFT_BRACKET:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x7B); @@ -239,7 +239,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_RBRC: +            case KC_RIGHT_BRACKET:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x7D); @@ -249,7 +249,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_BSLS: +            case KC_BACKSLASH:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x7C); diff --git a/quantum/process_keycode/process_printer_bb.c b/quantum/process_keycode/process_printer_bb.c index e482d82591..6c91bd27ef 100644 --- a/quantum/process_keycode/process_printer_bb.c +++ b/quantum/process_keycode/process_printer_bb.c @@ -45,7 +45,7 @@ uint8_t shifted_numbers[10] = {0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0  // uint8_t keycode_to_ascii[0xFF][2]; -// keycode_to_ascii[KC_MINS] = {0x2D, 0x5F}; +// keycode_to_ascii[KC_MINUS] = {0x2D, 0x5F};  void print_char(char c) {      uint8_t b = 8; @@ -84,8 +84,8 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {              case KC_PIPE:              case KC_TILD:                  keycode &= 0xFF; -            case KC_LSFT: -            case KC_RSFT: +            case KC_LEFT_SHIFT: +            case KC_RIGHT_SHIFT:                  if (record->event.pressed) {                      character_shift++;                  } else { @@ -101,13 +101,13 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                      print_string("This is a line of text!\n\n\n");                  }                  return false; -            case KC_ESC: +            case KC_ESCAPE:                  if (record->event.pressed) {                      print_char(0x1B);                  }                  return false;                  break; -            case KC_SPC: +            case KC_SPACE:                  if (record->event.pressed) {                      print_char(0x20);                  } @@ -133,7 +133,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_ENT: +            case KC_ENTER:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x0C); @@ -143,7 +143,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_BSPC: +            case KC_BACKSPACE:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x18); @@ -163,7 +163,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_COMM: +            case KC_COMMA:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x3C); @@ -173,7 +173,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_SLSH: +            case KC_SLASH:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x3F); @@ -183,7 +183,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_QUOT: +            case KC_QUOTE:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x22); @@ -193,7 +193,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_GRV: +            case KC_GRAVE:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x7E); @@ -203,7 +203,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_MINS: +            case KC_MINUS:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x5F); @@ -213,7 +213,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_EQL: +            case KC_EQUAL:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x2B); @@ -223,7 +223,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_LBRC: +            case KC_LEFT_BRACKET:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x7B); @@ -233,7 +233,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_RBRC: +            case KC_RIGHT_BRACKET:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x7D); @@ -243,7 +243,7 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {                  }                  return false;                  break; -            case KC_BSLS: +            case KC_BACKSLASH:                  if (record->event.pressed) {                      if (character_shift) {                          print_char(0x7C); diff --git a/quantum/process_keycode/process_programmable_button.c b/quantum/process_keycode/process_programmable_button.c new file mode 100644 index 0000000000..c6e77faacc --- /dev/null +++ b/quantum/process_keycode/process_programmable_button.c @@ -0,0 +1,31 @@ +/* +Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "process_programmable_button.h" +#include "programmable_button.h" + +bool process_programmable_button(uint16_t keycode, keyrecord_t *record) { +    if (keycode >= PROGRAMMABLE_BUTTON_MIN && keycode <= PROGRAMMABLE_BUTTON_MAX) { +        uint8_t button = keycode - PROGRAMMABLE_BUTTON_MIN + 1; +        if (record->event.pressed) { +            programmable_button_on(button); +        } else { +            programmable_button_off(button); +        } +    } +    return true; +} diff --git a/quantum/process_keycode/process_programmable_button.h b/quantum/process_keycode/process_programmable_button.h new file mode 100644 index 0000000000..47c6ce5614 --- /dev/null +++ b/quantum/process_keycode/process_programmable_button.h @@ -0,0 +1,23 @@ +/* +Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <stdint.h> +#include "quantum.h" + +bool process_programmable_button(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_space_cadet.c b/quantum/process_keycode/process_space_cadet.c index f99db2a87b..46b2648c35 100644 --- a/quantum/process_keycode/process_space_cadet.c +++ b/quantum/process_keycode/process_space_cadet.c @@ -27,53 +27,53 @@  // Shift / Enter setup  #ifndef SFTENT_KEY -#    define SFTENT_KEY KC_ENT +#    define SFTENT_KEY KC_ENTER  #endif  #ifdef DISABLE_SPACE_CADET_MODIFIER  #    ifndef LSPO_MOD -#        define LSPO_MOD KC_TRNS +#        define LSPO_MOD KC_TRANSPARENT  #    endif  #    ifndef RSPC_MOD -#        define RSPC_MOD KC_TRNS +#        define RSPC_MOD KC_TRANSPARENT  #    endif  #else  #    ifndef LSPO_MOD -#        define LSPO_MOD KC_LSFT +#        define LSPO_MOD KC_LEFT_SHIFT  #    endif  #    ifndef RSPC_MOD -#        define RSPC_MOD KC_RSFT +#        define RSPC_MOD KC_RIGHT_SHIFT  #    endif  #endif  // **********************************************************  // Shift / paren setup  #ifndef LSPO_KEYS -#    define LSPO_KEYS KC_LSFT, LSPO_MOD, LSPO_KEY +#    define LSPO_KEYS KC_LEFT_SHIFT, LSPO_MOD, LSPO_KEY  #endif  #ifndef RSPC_KEYS -#    define RSPC_KEYS KC_RSFT, RSPC_MOD, RSPC_KEY +#    define RSPC_KEYS KC_RIGHT_SHIFT, RSPC_MOD, RSPC_KEY  #endif  // Control / paren setup  #ifndef LCPO_KEYS -#    define LCPO_KEYS KC_LCTL, KC_LSFT, KC_9 +#    define LCPO_KEYS KC_LEFT_CTRL, KC_LEFT_SHIFT, KC_9  #endif  #ifndef RCPC_KEYS -#    define RCPC_KEYS KC_RCTL, KC_RSFT, KC_0 +#    define RCPC_KEYS KC_RIGHT_CTRL, KC_RIGHT_SHIFT, KC_0  #endif  // Alt / paren setup  #ifndef LAPO_KEYS -#    define LAPO_KEYS KC_LALT, KC_LSFT, KC_9 +#    define LAPO_KEYS KC_LEFT_ALT, KC_LEFT_SHIFT, KC_9  #endif  #ifndef RAPC_KEYS -#    define RAPC_KEYS KC_RALT, KC_RSFT, KC_0 +#    define RAPC_KEYS KC_RIGHT_ALT, KC_RIGHT_SHIFT, KC_0  #endif  // Shift / Enter setup  #ifndef SFTENT_KEYS -#    define SFTENT_KEYS KC_RSFT, KC_TRNS, SFTENT_KEY +#    define SFTENT_KEYS KC_RIGHT_SHIFT, KC_TRANSPARENT, SFTENT_KEY  #endif  static uint8_t  sc_last  = 0; diff --git a/quantum/process_keycode/process_steno.c b/quantum/process_keycode/process_steno.c index a964aead35..5d0bb313b4 100644 --- a/quantum/process_keycode/process_steno.c +++ b/quantum/process_keycode/process_steno.c @@ -67,7 +67,7 @@ static const uint8_t boltmap[64] PROGMEM = {TXB_NUL, TXB_NUM, TXB_NUM, TXB_NUM,  #ifdef STENO_COMBINEDMAP  /* Used to look up when pressing the middle row key to combine two consonant or vowel keys */ -static const uint16_t combinedmap_first[] PROGMEM = {STN_S1, STN_TL, STN_PL, STN_HL, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR, STN_A, STN_E}; +static const uint16_t combinedmap_first[] PROGMEM  = {STN_S1, STN_TL, STN_PL, STN_HL, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR, STN_A, STN_E};  static const uint16_t combinedmap_second[] PROGMEM = {STN_S2, STN_KL, STN_WL, STN_RL, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR, STN_O, STN_U};  #endif @@ -174,11 +174,10 @@ bool process_steno(uint16_t keycode, keyrecord_t *record) {              return false;  #ifdef STENO_COMBINEDMAP -        case QK_STENO_COMB ... QK_STENO_COMB_MAX: -        { +        case QK_STENO_COMB ... QK_STENO_COMB_MAX: {              uint8_t result; -            result = process_steno(combinedmap_first[keycode-QK_STENO_COMB], record); -            result &= process_steno(combinedmap_second[keycode-QK_STENO_COMB], record); +            result = process_steno(combinedmap_first[keycode - QK_STENO_COMB], record); +            result &= process_steno(combinedmap_second[keycode - QK_STENO_COMB], record);              return result;          }  #endif diff --git a/quantum/process_keycode/process_terminal.c b/quantum/process_keycode/process_terminal.c index 7d1eefa9ed..a059f3a521 100644 --- a/quantum/process_keycode/process_terminal.c +++ b/quantum/process_keycode/process_terminal.c @@ -257,12 +257,12 @@ bool process_terminal(uint16_t keycode, keyrecord_t *record) {                      process_terminal_command();                      return false;                      break; -                case KC_ESC: +                case KC_ESCAPE:                      SEND_STRING("\n");                      enable_terminal();                      return false;                      break; -                case KC_BSPC: +                case KC_BACKSPACE:                      str_len = strlen(buffer);                      if (str_len > 0) {                          buffer[str_len - 1] = 0; @@ -284,7 +284,7 @@ bool process_terminal(uint16_t keycode, keyrecord_t *record) {                          str_len = strlen(buffer);                          for (int i = 0; i < str_len; ++i) {                              send_string(SS_TAP(X_BSPACE));  // clear w/e is on the line already -                            // process_terminal(KC_BSPC,record); +                            // process_terminal(KC_BACKSPACE,record);                          }                          strncpy(buffer, cmd_buffer[current_cmd_buffer_pos], 80); @@ -299,7 +299,7 @@ bool process_terminal(uint16_t keycode, keyrecord_t *record) {                          str_len = strlen(buffer);                          for (int i = 0; i < str_len; ++i) {                              send_string(SS_TAP(X_BSPACE));  // clear w/e is on the line already -                            // process_terminal(KC_BSPC,record); +                            // process_terminal(KC_BACKSPACE,record);                          }                          strncpy(buffer, cmd_buffer[current_cmd_buffer_pos], 79); @@ -311,7 +311,7 @@ bool process_terminal(uint16_t keycode, keyrecord_t *record) {                  default:                      if (keycode <= 58) {                          char_to_add = 0; -                        if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) { +                        if (get_mods() & (MOD_BIT(KC_LEFT_SHIFT) | MOD_BIT(KC_RIGHT_SHIFT))) {                              char_to_add = shifted_keycode_to_ascii_lut[keycode];                          } else if (get_mods() == 0) {                              char_to_add = keycode_to_ascii_lut[keycode]; diff --git a/quantum/process_keycode/process_ucis.c b/quantum/process_keycode/process_ucis.c index 12b0aba9bf..d084d2b66c 100644 --- a/quantum/process_keycode/process_ucis.c +++ b/quantum/process_keycode/process_ucis.c @@ -46,7 +46,7 @@ static bool is_uni_seq(char *seq) {              return false;          }      } -    return qk_ucis_state.codes[i] == KC_ENT || qk_ucis_state.codes[i] == KC_SPC; +    return qk_ucis_state.codes[i] == KC_ENTER || qk_ucis_state.codes[i] == KC_SPACE;  }  __attribute__((weak)) void qk_ucis_symbol_fallback(void) { @@ -72,7 +72,7 @@ bool process_ucis(uint16_t keycode, keyrecord_t *record) {          return true;      } -    bool special = keycode == KC_SPC || keycode == KC_ENT || keycode == KC_ESC || keycode == KC_BSPC; +    bool special = keycode == KC_SPACE || keycode == KC_ENTER || keycode == KC_ESCAPE || keycode == KC_BACKSPACE;      if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH && !special) {          return false;      } @@ -81,7 +81,7 @@ bool process_ucis(uint16_t keycode, keyrecord_t *record) {      qk_ucis_state.count++;      switch (keycode) { -        case KC_BSPC: +        case KC_BACKSPACE:              if (qk_ucis_state.count >= 2) {                  qk_ucis_state.count -= 2;                  return true; @@ -90,16 +90,16 @@ bool process_ucis(uint16_t keycode, keyrecord_t *record) {                  return false;              } -        case KC_SPC: -        case KC_ENT: -        case KC_ESC: +        case KC_SPACE: +        case KC_ENTER: +        case KC_ESCAPE:              for (uint8_t i = 0; i < qk_ucis_state.count; i++) { -                register_code(KC_BSPC); -                unregister_code(KC_BSPC); +                register_code(KC_BACKSPACE); +                unregister_code(KC_BACKSPACE);                  wait_ms(UNICODE_TYPE_DELAY);              } -            if (keycode == KC_ESC) { +            if (keycode == KC_ESCAPE) {                  qk_ucis_state.in_progress = false;                  qk_ucis_cancel();                  return false; diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c index 46fcaaa86b..9c82571c7d 100644 --- a/quantum/process_keycode/process_unicode_common.c +++ b/quantum/process_keycode/process_unicode_common.c @@ -22,6 +22,7 @@  unicode_config_t unicode_config;  uint8_t          unicode_saved_mods;  bool             unicode_saved_caps_lock; +bool             unicode_saved_num_lock;  #if UNICODE_SELECTED_MODES != -1  static uint8_t selected[]     = {UNICODE_SELECTED_MODES}; @@ -79,13 +80,14 @@ void persist_unicode_input_mode(void) { eeprom_update_byte(EECONFIG_UNICODEMODE,  __attribute__((weak)) void unicode_input_start(void) {      unicode_saved_caps_lock = host_keyboard_led_state().caps_lock; +    unicode_saved_num_lock  = host_keyboard_led_state().num_lock;      // Note the order matters here!      // Need to do this before we mess around with the mods, or else      // UNICODE_KEY_LNX (which is usually Ctrl-Shift-U) might not work      // correctly in the shifted case.      if (unicode_config.input_mode == UC_LNX && unicode_saved_caps_lock) { -        tap_code(KC_CAPS); +        tap_code(KC_CAPS_LOCK);      }      unicode_saved_mods = get_mods();  // Save current mods @@ -99,8 +101,12 @@ __attribute__((weak)) void unicode_input_start(void) {              tap_code16(UNICODE_KEY_LNX);              break;          case UC_WIN: -            register_code(KC_LALT); -            tap_code(KC_PPLS); +            // For increased reliability, use numpad keys for inputting digits +            if (!unicode_saved_num_lock) { +                tap_code(KC_NUM_LOCK); +            } +            register_code(KC_LEFT_ALT); +            tap_code(KC_KP_PLUS);              break;          case UC_WINC:              tap_code(UNICODE_KEY_WINC); @@ -117,13 +123,16 @@ __attribute__((weak)) void unicode_input_finish(void) {              unregister_code(UNICODE_KEY_MAC);              break;          case UC_LNX: -            tap_code(KC_SPC); +            tap_code(KC_SPACE);              if (unicode_saved_caps_lock) { -                tap_code(KC_CAPS); +                tap_code(KC_CAPS_LOCK);              }              break;          case UC_WIN: -            unregister_code(KC_LALT); +            unregister_code(KC_LEFT_ALT); +            if (!unicode_saved_num_lock) { +                tap_code(KC_NUM_LOCK); +            }              break;          case UC_WINC:              tap_code(KC_ENTER); @@ -139,26 +148,44 @@ __attribute__((weak)) void unicode_input_cancel(void) {              unregister_code(UNICODE_KEY_MAC);              break;          case UC_LNX: -            tap_code(KC_ESC); +            tap_code(KC_ESCAPE);              if (unicode_saved_caps_lock) { -                tap_code(KC_CAPS); +                tap_code(KC_CAPS_LOCK);              }              break;          case UC_WINC: -            tap_code(KC_ESC); +            tap_code(KC_ESCAPE);              break;          case UC_WIN: -            unregister_code(KC_LALT); +            unregister_code(KC_LEFT_ALT); +            if (!unicode_saved_num_lock) { +                tap_code(KC_NUM_LOCK); +            }              break;      }      set_mods(unicode_saved_mods);  // Reregister previously set mods  } +// clang-format off + +static void send_nibble_wrapper(uint8_t digit) { +    if (unicode_config.input_mode == UC_WIN) { +        uint8_t kc = digit < 10 +                   ? KC_KP_1 + (10 + digit - 1) % 10 +                   : KC_A + (digit - 10); +        tap_code(kc); +        return; +    } +    send_nibble(digit); +} + +// clang-format on +  void register_hex(uint16_t hex) {      for (int i = 3; i >= 0; i--) {          uint8_t digit = ((hex >> (i * 4)) & 0xF); -        send_nibble(digit); +        send_nibble_wrapper(digit);      }  } @@ -171,10 +198,10 @@ void register_hex32(uint32_t hex) {          uint8_t digit = ((hex >> (i * 4)) & 0xF);          if (digit == 0) {              if (!onzerostart) { -                send_nibble(digit); +                send_nibble_wrapper(digit);              }          } else { -            send_nibble(digit); +            send_nibble_wrapper(digit);              onzerostart = false;          }      } diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h index c10e171ec3..72defb445e 100644 --- a/quantum/process_keycode/process_unicode_common.h +++ b/quantum/process_keycode/process_unicode_common.h @@ -24,13 +24,13 @@  // Keycodes used for starting Unicode input on different platforms  #ifndef UNICODE_KEY_MAC -#    define UNICODE_KEY_MAC KC_LALT +#    define UNICODE_KEY_MAC KC_LEFT_ALT  #endif  #ifndef UNICODE_KEY_LNX  #    define UNICODE_KEY_LNX LCTL(LSFT(KC_U))  #endif  #ifndef UNICODE_KEY_WINC -#    define UNICODE_KEY_WINC KC_RALT +#    define UNICODE_KEY_WINC KC_RIGHT_ALT  #endif  // Comma-delimited, ordered list of input modes selected for use (e.g. in cycle) diff --git a/quantum/programmable_button.c b/quantum/programmable_button.c new file mode 100644 index 0000000000..be828fd17c --- /dev/null +++ b/quantum/programmable_button.c @@ -0,0 +1,37 @@ +/* +Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "programmable_button.h" +#include "host.h" + +#define REPORT_BIT(index) (((uint32_t)1) << (index - 1)) + +static uint32_t programmable_button_report = 0; + +void programmable_button_clear(void) { programmable_button_report = 0; } + +void programmable_button_send(void) { host_programmable_button_send(programmable_button_report); } + +void programmable_button_on(uint8_t index) { programmable_button_report |= REPORT_BIT(index); } + +void programmable_button_off(uint8_t index) { programmable_button_report &= ~REPORT_BIT(index); } + +bool programmable_button_is_on(uint8_t index) { return !!(programmable_button_report & REPORT_BIT(index)); }; + +uint32_t programmable_button_get_report(void) { return programmable_button_report; }; + +void programmable_button_set_report(uint32_t report) { programmable_button_report = report; } diff --git a/quantum/programmable_button.h b/quantum/programmable_button.h new file mode 100644 index 0000000000..e89b8b9fd6 --- /dev/null +++ b/quantum/programmable_button.h @@ -0,0 +1,30 @@ +/* +Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <stdint.h> +#include <stdbool.h> +#include "report.h" + +void     programmable_button_clear(void); +void     programmable_button_send(void); +void     programmable_button_on(uint8_t index); +void     programmable_button_off(uint8_t index); +bool     programmable_button_is_on(uint8_t index); +uint32_t programmable_button_get_report(void); +void     programmable_button_set_report(uint32_t report); diff --git a/quantum/quantum.c b/quantum/quantum.c index e60378afe4..0eca329f08 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -25,10 +25,6 @@  #    include "backlight.h"  #endif -#ifdef API_ENABLE -#    include "api.h" -#endif -  #ifdef MIDI_ENABLE  #    include "process_midi.h"  #endif @@ -66,15 +62,15 @@ uint8_t extract_mod_bits(uint16_t code) {      uint8_t mods_to_send = 0;      if (code & QK_RMODS_MIN) {  // Right mod flag is set -        if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RCTL); -        if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RSFT); -        if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RALT); -        if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_RGUI); +        if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RIGHT_CTRL); +        if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RIGHT_SHIFT); +        if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RIGHT_ALT); +        if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_RIGHT_GUI);      } else { -        if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_LCTL); -        if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_LSFT); -        if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_LALT); -        if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_LGUI); +        if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_LEFT_CTRL); +        if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_LEFT_SHIFT); +        if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_LEFT_ALT); +        if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_LEFT_GUI);      }      return mods_to_send; @@ -145,12 +141,13 @@ void reset_keyboard(void) {  /* Convert record into usable keycode via the contained event. */  uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache) {  #ifdef COMBO_ENABLE -    if (record->keycode) { return record->keycode; } +    if (record->keycode) { +        return record->keycode; +    }  #endif      return get_event_keycode(record->event, update_layer_cache);  } -  /* Convert event into usable keycode. Checks the layer cache to ensure that it   * retains the correct keycode after a layer change, if the key is still pressed.   * "update_layer_cache" is to ensure that it only updates the layer cache when @@ -179,12 +176,12 @@ uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache) {  bool pre_process_record_quantum(keyrecord_t *record) {      if (!(  #ifdef COMBO_ENABLE -        process_combo(get_record_keycode(record, true), record) && +            process_combo(get_record_keycode(record, true), record) &&  #endif -        true)) { +            true)) {          return false;      } -    return true; // continue processing +    return true;  // continue processing  }  /* Get keycode, and then call keyboard function */ @@ -296,6 +293,9 @@ bool process_record_quantum(keyrecord_t *record) {  #ifdef JOYSTICK_ENABLE              process_joystick(keycode, record) &&  #endif +#ifdef PROGRAMMABLE_BUTTON_ENABLE +            process_programmable_button(keycode, record) && +#endif              true)) {          return false;      } @@ -465,14 +465,6 @@ void matrix_scan_quantum() {  #    include "hd44780.h"  #endif -void api_send_unicode(uint32_t unicode) { -#ifdef API_ENABLE -    uint8_t chunk[4]; -    dword_to_bytes(unicode, chunk); -    MT_SEND_DATA(DT_UNICODE, chunk, 5); -#endif -} -  //------------------------------------------------------------------------------  // Override these functions in your keymap file to play different tunes on  // different events such as startup and bootloader jump @@ -480,3 +472,99 @@ void api_send_unicode(uint32_t unicode) {  __attribute__((weak)) void startup_user() {}  __attribute__((weak)) void shutdown_user() {} + +/** \brief Run keyboard level Power down + * + * FIXME: needs doc + */ +__attribute__((weak)) void suspend_power_down_user(void) {} +/** \brief Run keyboard level Power down + * + * FIXME: needs doc + */ +__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); } + +void suspend_power_down_quantum(void) { +#ifndef NO_SUSPEND_POWER_DOWN +// Turn off backlight +#    ifdef BACKLIGHT_ENABLE +    backlight_set(0); +#    endif + +#    ifdef LED_MATRIX_ENABLE +    led_matrix_task(); +#    endif +#    ifdef RGB_MATRIX_ENABLE +    rgb_matrix_task(); +#    endif + +    // Turn off LED indicators +    uint8_t leds_off = 0; +#    if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) +    if (is_backlight_enabled()) { +        // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off +        leds_off |= (1 << USB_LED_CAPS_LOCK); +    } +#    endif +    led_set(leds_off); + +// Turn off audio +#    ifdef AUDIO_ENABLE +    stop_all_notes(); +#    endif + +// Turn off underglow +#    if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) +    rgblight_suspend(); +#    endif + +#    if defined(LED_MATRIX_ENABLE) +    led_matrix_set_suspend_state(true); +#    endif +#    if defined(RGB_MATRIX_ENABLE) +    rgb_matrix_set_suspend_state(true); +#    endif + +#    ifdef OLED_ENABLE +    oled_off(); +#    endif +#    ifdef ST7565_ENABLE +    st7565_off(); +#    endif +#endif +} + +/** \brief run user level code immediately after wakeup + * + * FIXME: needs doc + */ +__attribute__((weak)) void suspend_wakeup_init_user(void) {} + +/** \brief run keyboard level code immediately after wakeup + * + * FIXME: needs doc + */ +__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } + +__attribute__((weak)) void suspend_wakeup_init_quantum(void) { +// Turn on backlight +#ifdef BACKLIGHT_ENABLE +    backlight_init(); +#endif + +    // Restore LED indicators +    led_set(host_keyboard_leds()); + +// Wake up underglow +#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) +    rgblight_wakeup(); +#endif + +#if defined(LED_MATRIX_ENABLE) +    led_matrix_set_suspend_state(false); +#endif +#if defined(RGB_MATRIX_ENABLE) +    rgb_matrix_set_suspend_state(false); +#endif +    suspend_wakeup_init_kb(); +} diff --git a/quantum/quantum.h b/quantum/quantum.h index 86b717e445..9250f5acce 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -147,6 +147,10 @@ extern layer_state_t layer_state;  #    include "process_joystick.h"  #endif +#ifdef PROGRAMMABLE_BUTTON_ENABLE +#    include "process_programmable_button.h" +#endif +  #ifdef GRAVE_ESC_ENABLE  #    include "process_grave_esc.h"  #endif @@ -233,5 +237,3 @@ void led_set_user(uint8_t usb_led);  void led_set_kb(uint8_t usb_led);  bool led_update_user(led_t led_state);  bool led_update_kb(led_t led_state); - -void api_send_unicode(uint32_t unicode); diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index ef4b0f457b..cde97074d3 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -19,7 +19,7 @@  #include "sequencer.h"  // Fillers to make layering more clear -#define _______ KC_TRNS +#define _______ KC_TRANSPARENT  #define XXXXXXX KC_NO  enum quantum_keycodes { @@ -524,6 +524,40 @@ enum quantum_keycodes {      // Additional magic key      MAGIC_TOGGLE_GUI, +    // Programmable Button +    PROGRAMMABLE_BUTTON_1, +    PROGRAMMABLE_BUTTON_2, +    PROGRAMMABLE_BUTTON_3, +    PROGRAMMABLE_BUTTON_4, +    PROGRAMMABLE_BUTTON_5, +    PROGRAMMABLE_BUTTON_6, +    PROGRAMMABLE_BUTTON_7, +    PROGRAMMABLE_BUTTON_8, +    PROGRAMMABLE_BUTTON_9, +    PROGRAMMABLE_BUTTON_10, +    PROGRAMMABLE_BUTTON_11, +    PROGRAMMABLE_BUTTON_12, +    PROGRAMMABLE_BUTTON_13, +    PROGRAMMABLE_BUTTON_14, +    PROGRAMMABLE_BUTTON_15, +    PROGRAMMABLE_BUTTON_16, +    PROGRAMMABLE_BUTTON_17, +    PROGRAMMABLE_BUTTON_18, +    PROGRAMMABLE_BUTTON_19, +    PROGRAMMABLE_BUTTON_20, +    PROGRAMMABLE_BUTTON_21, +    PROGRAMMABLE_BUTTON_22, +    PROGRAMMABLE_BUTTON_23, +    PROGRAMMABLE_BUTTON_24, +    PROGRAMMABLE_BUTTON_25, +    PROGRAMMABLE_BUTTON_26, +    PROGRAMMABLE_BUTTON_27, +    PROGRAMMABLE_BUTTON_28, +    PROGRAMMABLE_BUTTON_29, +    PROGRAMMABLE_BUTTON_30, +    PROGRAMMABLE_BUTTON_31, +    PROGRAMMABLE_BUTTON_32, +      // Start of custom keycode range for keyboards and keymaps - always leave at the end      SAFE_RANGE  }; @@ -565,69 +599,67 @@ enum quantum_keycodes {  #define MOD_MEH 0x7  // US ANSI shifted keycode aliases -#define KC_TILD LSFT(KC_GRV)  // ~ -#define KC_TILDE KC_TILD +#define KC_TILDE LSFT(KC_GRAVE)  // ~ +#define KC_TILD KC_TILDE -#define KC_EXLM LSFT(KC_1)  // ! -#define KC_EXCLAIM KC_EXLM +#define KC_EXCLAIM LSFT(KC_1)  // ! +#define KC_EXLM KC_EXCLAIM  #define KC_AT LSFT(KC_2)  // @  #define KC_HASH LSFT(KC_3)  // # -#define KC_DLR LSFT(KC_4)  // $ -#define KC_DOLLAR KC_DLR - -#define KC_PERC LSFT(KC_5)  // % -#define KC_PERCENT KC_PERC +#define KC_DOLLAR LSFT(KC_4)  // $ +#define KC_DLR KC_DOLLAR -#define KC_CIRC LSFT(KC_6)  // ^ -#define KC_CIRCUMFLEX KC_CIRC +#define KC_PERCENT LSFT(KC_5)  // % +#define KC_PERC KC_PERCENT -#define KC_AMPR LSFT(KC_7)  // & -#define KC_AMPERSAND KC_AMPR +#define KC_CIRCUMFLEX LSFT(KC_6)  // ^ +#define KC_CIRC KC_CIRCUMFLEX -#define KC_ASTR LSFT(KC_8)  // * -#define KC_ASTERISK KC_ASTR +#define KC_AMPERSAND LSFT(KC_7)  // & +#define KC_AMPR KC_AMPERSAND -#define KC_LPRN LSFT(KC_9)  // ( -#define KC_LEFT_PAREN KC_LPRN +#define KC_ASTERISK LSFT(KC_8)  // * +#define KC_ASTR KC_ASTERISK -#define KC_RPRN LSFT(KC_0)  // ) -#define KC_RIGHT_PAREN KC_RPRN +#define KC_LEFT_PAREN LSFT(KC_9)  // ( +#define KC_LPRN KC_LEFT_PAREN -#define KC_UNDS LSFT(KC_MINS)  // _ -#define KC_UNDERSCORE KC_UNDS +#define KC_RIGHT_PAREN LSFT(KC_0)  // ) +#define KC_RPRN KC_RIGHT_PAREN -#define KC_PLUS LSFT(KC_EQL)  // + +#define KC_UNDERSCORE LSFT(KC_MINUS)  // _ +#define KC_UNDS KC_UNDERSCORE -#define KC_LCBR LSFT(KC_LBRC)  // { -#define KC_LEFT_CURLY_BRACE KC_LCBR +#define KC_PLUS LSFT(KC_EQUAL)  // + -#define KC_RCBR LSFT(KC_RBRC)  // } -#define KC_RIGHT_CURLY_BRACE KC_RCBR +#define KC_LEFT_CURLY_BRACE LSFT(KC_LEFT_BRACKET)  // { +#define KC_LCBR KC_LEFT_CURLY_BRACE -#define KC_LABK LSFT(KC_COMM)  // < -#define KC_LEFT_ANGLE_BRACKET KC_LABK +#define KC_RIGHT_CURLY_BRACE LSFT(KC_RIGHT_BRACKET)  // } +#define KC_RCBR KC_RIGHT_CURLY_BRACE -#define KC_RABK LSFT(KC_DOT)  // > -#define KC_RIGHT_ANGLE_BRACKET KC_RABK +#define KC_LEFT_ANGLE_BRACKET LSFT(KC_COMMA)  // < +#define KC_LABK KC_LEFT_ANGLE_BRACKET +#define KC_LT KC_LEFT_ANGLE_BRACKET -#define KC_COLN LSFT(KC_SCLN)  // : -#define KC_COLON KC_COLN +#define KC_RIGHT_ANGLE_BRACKET LSFT(KC_DOT)  // > +#define KC_RABK KC_RIGHT_ANGLE_BRACKET +#define KC_GT KC_RIGHT_ANGLE_BRACKET -#define KC_PIPE LSFT(KC_BSLS)  // | +#define KC_COLON LSFT(KC_SEMICOLON)  // : +#define KC_COLN KC_COLON -#define KC_LT LSFT(KC_COMM)  // < +#define KC_PIPE LSFT(KC_BACKSLASH)  // | -#define KC_GT LSFT(KC_DOT)  // > +#define KC_QUESTION LSFT(KC_SLASH)  // ? +#define KC_QUES KC_QUESTION -#define KC_QUES LSFT(KC_SLSH)  // ? -#define KC_QUESTION KC_QUES - -#define KC_DQT LSFT(KC_QUOT)  // " -#define KC_DOUBLE_QUOTE KC_DQT -#define KC_DQUO KC_DQT +#define KC_DOUBLE_QUOTE LSFT(KC_QUOTE)  // " +#define KC_DQUO KC_DOUBLE_QUOTE +#define KC_DQT KC_DOUBLE_QUOTE  #define KC_DELT KC_DELETE  // Del key (four letter code) @@ -775,12 +807,12 @@ enum quantum_keycodes {  #define CMD_T(kc) LCMD_T(kc)  #define WIN_T(kc) LWIN_T(kc) -#define C_S_T(kc) MT(MOD_LCTL | MOD_LSFT, kc)  // Left Control + Shift e.g. for gnome-terminal -#define MEH_T(kc) MT(MOD_LCTL | MOD_LSFT | MOD_LALT, kc)  // Meh is a less hyper version of the Hyper key -- doesn't include GUI, so just Left Control + Shift + Alt -#define LCAG_T(kc) MT(MOD_LCTL | MOD_LALT | MOD_LGUI, kc)  // Left Control + Alt + GUI -#define RCAG_T(kc) MT(MOD_RCTL | MOD_RALT | MOD_RGUI, kc)  // Right Control + Alt + GUI +#define C_S_T(kc) MT(MOD_LCTL | MOD_LSFT, kc)                         // Left Control + Shift e.g. for gnome-terminal +#define MEH_T(kc) MT(MOD_LCTL | MOD_LSFT | MOD_LALT, kc)              // Meh is a less hyper version of the Hyper key -- doesn't include GUI, so just Left Control + Shift + Alt +#define LCAG_T(kc) MT(MOD_LCTL | MOD_LALT | MOD_LGUI, kc)             // Left Control + Alt + GUI +#define RCAG_T(kc) MT(MOD_RCTL | MOD_RALT | MOD_RGUI, kc)             // Right Control + Alt + GUI  #define HYPR_T(kc) MT(MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI, kc)  // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ -#define LSG_T(kc) MT(MOD_LSFT | MOD_LGUI, kc)  // Left Shift + GUI +#define LSG_T(kc) MT(MOD_LSFT | MOD_LGUI, kc)                         // Left Shift + GUI  #define SGUI_T(kc) LSG_T(kc)  #define SCMD_T(kc) LSG_T(kc)  #define SWIN_T(kc) LSG_T(kc) @@ -811,7 +843,7 @@ enum quantum_keycodes {  #define UC_M_MA UNICODE_MODE_MAC  #define UNICODE_MODE_OSX UNICODE_MODE_MAC  // Deprecated alias -#define UC_M_OS UNICODE_MODE_MAC  // Deprecated alias +#define UC_M_OS UNICODE_MODE_MAC           // Deprecated alias  #define UC_M_LN UNICODE_MODE_LNX  #define UC_M_WI UNICODE_MODE_WIN  #define UC_M_BS UNICODE_MODE_BSD @@ -854,3 +886,39 @@ enum quantum_keycodes {  #define OS_TOGG ONESHOT_TOGGLE  #define OS_ON ONESHOT_ENABLE  #define OS_OFF ONESHOT_DISABLE + +// Programmable Button aliases +#define PB_1 PROGRAMMABLE_BUTTON_1 +#define PB_2 PROGRAMMABLE_BUTTON_2 +#define PB_3 PROGRAMMABLE_BUTTON_3 +#define PB_4 PROGRAMMABLE_BUTTON_4 +#define PB_5 PROGRAMMABLE_BUTTON_5 +#define PB_6 PROGRAMMABLE_BUTTON_6 +#define PB_7 PROGRAMMABLE_BUTTON_7 +#define PB_8 PROGRAMMABLE_BUTTON_8 +#define PB_9 PROGRAMMABLE_BUTTON_9 +#define PB_10 PROGRAMMABLE_BUTTON_10 +#define PB_11 PROGRAMMABLE_BUTTON_11 +#define PB_12 PROGRAMMABLE_BUTTON_12 +#define PB_13 PROGRAMMABLE_BUTTON_13 +#define PB_14 PROGRAMMABLE_BUTTON_14 +#define PB_15 PROGRAMMABLE_BUTTON_15 +#define PB_16 PROGRAMMABLE_BUTTON_16 +#define PB_17 PROGRAMMABLE_BUTTON_17 +#define PB_18 PROGRAMMABLE_BUTTON_18 +#define PB_19 PROGRAMMABLE_BUTTON_19 +#define PB_20 PROGRAMMABLE_BUTTON_20 +#define PB_21 PROGRAMMABLE_BUTTON_21 +#define PB_22 PROGRAMMABLE_BUTTON_22 +#define PB_23 PROGRAMMABLE_BUTTON_23 +#define PB_24 PROGRAMMABLE_BUTTON_24 +#define PB_25 PROGRAMMABLE_BUTTON_25 +#define PB_26 PROGRAMMABLE_BUTTON_26 +#define PB_27 PROGRAMMABLE_BUTTON_27 +#define PB_28 PROGRAMMABLE_BUTTON_28 +#define PB_29 PROGRAMMABLE_BUTTON_29 +#define PB_30 PROGRAMMABLE_BUTTON_30 +#define PB_31 PROGRAMMABLE_BUTTON_31 +#define PB_32 PROGRAMMABLE_BUTTON_32 +#define PROGRAMMABLE_BUTTON_MIN PROGRAMMABLE_BUTTON_1 +#define PROGRAMMABLE_BUTTON_MAX PROGRAMMABLE_BUTTON_32 diff --git a/quantum/raw_hid.h b/quantum/raw_hid.h new file mode 100644 index 0000000000..6d60ab2bff --- /dev/null +++ b/quantum/raw_hid.h @@ -0,0 +1,5 @@ +#pragma once + +void raw_hid_receive(uint8_t *data, uint8_t length); + +void raw_hid_send(uint8_t *data, uint8_t length); diff --git a/quantum/rgb_matrix/animations/alpha_mods_anim.h b/quantum/rgb_matrix/animations/alpha_mods_anim.h index 3f2c9b799a..b8f5072681 100644 --- a/quantum/rgb_matrix/animations/alpha_mods_anim.h +++ b/quantum/rgb_matrix/animations/alpha_mods_anim.h @@ -19,7 +19,7 @@ bool ALPHAS_MODS(effect_params_t* params) {              rgb_matrix_set_color(i, rgb1.r, rgb1.g, rgb1.b);          }      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  }  #    endif  // RGB_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/rgb_matrix/animations/breathing_anim.h b/quantum/rgb_matrix/animations/breathing_anim.h index a00ccb83a2..baac51ed15 100644 --- a/quantum/rgb_matrix/animations/breathing_anim.h +++ b/quantum/rgb_matrix/animations/breathing_anim.h @@ -13,7 +13,7 @@ bool BREATHING(effect_params_t* params) {          RGB_MATRIX_TEST_LED_FLAGS();          rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  }  #    endif  // RGB_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/rgb_matrix/animations/fractal_anim.h b/quantum/rgb_matrix/animations/fractal_anim.h new file mode 100644 index 0000000000..83a69daa60 --- /dev/null +++ b/quantum/rgb_matrix/animations/fractal_anim.h @@ -0,0 +1,74 @@ +/* Copyright (C) 2021 @filterpaper + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +// Inspired from 4x12 fractal created by @schwarzgrau + +#ifdef ENABLE_RGB_MATRIX_FRACTAL +RGB_MATRIX_EFFECT(FRACTAL) +#    ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS + +static bool FRACTAL(effect_params_t* params) { +#        define MID_COL MATRIX_COLS / 2 +    static bool led[MATRIX_ROWS][MATRIX_COLS]; + +    static uint32_t wait_timer = 0; +    if (wait_timer > g_rgb_timer) { +        return false; +    } + +    inline uint32_t interval(void) { return 3000 / scale16by8(qadd8(rgb_matrix_config.speed, 16), 16); } + +    RGB rgb = rgb_matrix_hsv_to_rgb(rgb_matrix_config.hsv); +    for (uint8_t h = 0; h < MATRIX_ROWS; ++h) { +        for (uint8_t l = 0; l < MID_COL - 1; ++l) {  // Light and move left columns outwards +            if (led[h][l]) { +                rgb_matrix_set_color(g_led_config.matrix_co[h][l], rgb.r, rgb.g, rgb.b); +            } else { +                rgb_matrix_set_color(g_led_config.matrix_co[h][l], 0, 0, 0); +            } +            led[h][l] = led[h][l + 1]; +        } + +        for (uint8_t r = MATRIX_COLS - 1; r > MID_COL; --r) {  // Light and move right columns outwards +            if (led[h][r]) { +                rgb_matrix_set_color(g_led_config.matrix_co[h][r], rgb.r, rgb.g, rgb.b); +            } else { +                rgb_matrix_set_color(g_led_config.matrix_co[h][r], 0, 0, 0); +            } +            led[h][r] = led[h][r - 1]; +        } + +        // Light both middle columns +        if (led[h][MID_COL]) { +            rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL], rgb.r, rgb.g, rgb.b); +        } else { +            rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL], 0, 0, 0); +        } +        if (led[h][MID_COL - 1]) { +            rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL - 1], rgb.r, rgb.g, rgb.b); +        } else { +            rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL - 1], 0, 0, 0); +        } + +        // Generate new random fractal columns +        led[h][MID_COL] = led[h][MID_COL - 1] = (random8() & 3) ? false : true; +    } + +    wait_timer = g_rgb_timer + interval(); +    return false; +} +#    endif  // RGB_MATRIX_CUSTOM_EFFECT_IMPLS +#endif      // ENABLE_RGB_MATRIX_FRACTAL diff --git a/quantum/rgb_matrix/animations/gradient_left_right_anim.h b/quantum/rgb_matrix/animations/gradient_left_right_anim.h index b4f2752ff7..8b13d4e488 100644 --- a/quantum/rgb_matrix/animations/gradient_left_right_anim.h +++ b/quantum/rgb_matrix/animations/gradient_left_right_anim.h @@ -15,7 +15,7 @@ bool GRADIENT_LEFT_RIGHT(effect_params_t* params) {          RGB rgb = rgb_matrix_hsv_to_rgb(hsv);          rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  }  #    endif  // RGB_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/rgb_matrix/animations/gradient_up_down_anim.h b/quantum/rgb_matrix/animations/gradient_up_down_anim.h index 3fd45cf99b..7431ddcd99 100644 --- a/quantum/rgb_matrix/animations/gradient_up_down_anim.h +++ b/quantum/rgb_matrix/animations/gradient_up_down_anim.h @@ -15,7 +15,7 @@ bool GRADIENT_UP_DOWN(effect_params_t* params) {          RGB rgb = rgb_matrix_hsv_to_rgb(hsv);          rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  }  #    endif  // RGB_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/rgb_matrix/animations/hue_breathing_anim.h b/quantum/rgb_matrix/animations/hue_breathing_anim.h index 6d974b8c39..82be1a4424 100644 --- a/quantum/rgb_matrix/animations/hue_breathing_anim.h +++ b/quantum/rgb_matrix/animations/hue_breathing_anim.h @@ -15,7 +15,7 @@ bool HUE_BREATHING(effect_params_t* params) {          RGB_MATRIX_TEST_LED_FLAGS();          rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  }  #    endif  // RGB_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h b/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h index 7d8eafffb9..d639ba9b6c 100644 --- a/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h +++ b/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h @@ -22,7 +22,7 @@ bool JELLYBEAN_RAINDROPS(effect_params_t* params) {      for (int i = led_min; i < led_max; i++) {          jellybean_raindrops_set_color(i, params);      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  }  #    endif  // RGB_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/rgb_matrix/animations/pixel_rain_anim.h b/quantum/rgb_matrix/animations/pixel_rain_anim.h new file mode 100644 index 0000000000..0209d33033 --- /dev/null +++ b/quantum/rgb_matrix/animations/pixel_rain_anim.h @@ -0,0 +1,44 @@ +/* Copyright (C) 2021 @filterpaper + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef ENABLE_RGB_MATRIX_PIXEL_RAIN +RGB_MATRIX_EFFECT(PIXEL_RAIN) +#   ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS + +static bool PIXEL_RAIN(effect_params_t* params) { +    static uint32_t wait_timer = 0; +    if (wait_timer > g_rgb_timer) { return false; } + +    inline uint32_t interval(void) { return 500 / scale16by8(qadd8(rgb_matrix_config.speed, 16), 16); } + +    bool rain_pixel(uint8_t i, effect_params_t* params, bool off) { +        if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) { return true; } +        if (off) { +            rgb_matrix_set_color(i, 0,0,0); +        } else { +            HSV hsv = {random8(), qadd8(random8() >> 1, 127), rgb_matrix_config.hsv.v}; +            RGB rgb = rgb_matrix_hsv_to_rgb(hsv); +            rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); +        } +        wait_timer = g_rgb_timer + interval(); +        return false; +    } + +    return rain_pixel(mod8(random8(), DRIVER_LED_TOTAL), params, random8() & 2); +} + +#   endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS +#endif    // ENABLE_RGB_MATRIX_PIXEL_RAIN diff --git a/quantum/rgb_matrix/animations/raindrops_anim.h b/quantum/rgb_matrix/animations/raindrops_anim.h index c01688e2c7..fa61f9e0b9 100644 --- a/quantum/rgb_matrix/animations/raindrops_anim.h +++ b/quantum/rgb_matrix/animations/raindrops_anim.h @@ -32,7 +32,7 @@ bool RAINDROPS(effect_params_t* params) {      for (int i = led_min; i < led_max; i++) {          raindrops_set_color(i, params);      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  }  #    endif  // RGB_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/rgb_matrix/animations/rgb_matrix_effects.inc b/quantum/rgb_matrix/animations/rgb_matrix_effects.inc index 302ad79c04..8ecf4367ff 100644 --- a/quantum/rgb_matrix/animations/rgb_matrix_effects.inc +++ b/quantum/rgb_matrix/animations/rgb_matrix_effects.inc @@ -26,6 +26,8 @@  #include "hue_breathing_anim.h"  #include "hue_pendulum_anim.h"  #include "hue_wave_anim.h" +#include "fractal_anim.h" +#include "pixel_rain_anim.h"  #include "typing_heatmap_anim.h"  #include "digital_rain_anim.h"  #include "solid_reactive_simple_anim.h" diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h index 4867609c81..2ad0f22c28 100644 --- a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h +++ b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h @@ -13,5 +13,5 @@ bool effect_runner_dx_dy(effect_params_t* params, dx_dy_f effect_func) {          RGB     rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, dx, dy, time));          rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  } diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h index 9545b418d9..bcae7c79b6 100644 --- a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h +++ b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h @@ -14,5 +14,5 @@ bool effect_runner_dx_dy_dist(effect_params_t* params, dx_dy_dist_f effect_func)          RGB     rgb  = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, dx, dy, dist, time));          rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  } diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_i.h b/quantum/rgb_matrix/animations/runners/effect_runner_i.h index 1881cd6c60..b4de2992b6 100644 --- a/quantum/rgb_matrix/animations/runners/effect_runner_i.h +++ b/quantum/rgb_matrix/animations/runners/effect_runner_i.h @@ -11,5 +11,5 @@ bool effect_runner_i(effect_params_t* params, i_f effect_func) {          RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, i, time));          rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  } diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h b/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h index 75b7c0df4e..d5c1a26cef 100644 --- a/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h +++ b/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h @@ -23,7 +23,7 @@ bool effect_runner_reactive(effect_params_t* params, reactive_f effect_func) {          RGB      rgb    = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, offset));          rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  }  #endif  // RGB_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h b/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h index 2e46ffb350..d3a6e4e72f 100644 --- a/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h +++ b/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h @@ -23,7 +23,7 @@ bool effect_runner_reactive_splash(uint8_t start, effect_params_t* params, react          RGB rgb = rgb_matrix_hsv_to_rgb(hsv);          rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  }  #endif  // RGB_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h b/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h index 02351de51e..7776491d51 100644 --- a/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h +++ b/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h @@ -13,5 +13,5 @@ bool effect_runner_sin_cos_i(effect_params_t* params, sin_cos_i_f effect_func) {          RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, cos_value, sin_value, i, time));          rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  } diff --git a/quantum/rgb_matrix/animations/solid_color_anim.h b/quantum/rgb_matrix/animations/solid_color_anim.h index 79d63cf133..4209959468 100644 --- a/quantum/rgb_matrix/animations/solid_color_anim.h +++ b/quantum/rgb_matrix/animations/solid_color_anim.h @@ -9,7 +9,7 @@ bool SOLID_COLOR(effect_params_t* params) {          RGB_MATRIX_TEST_LED_FLAGS();          rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);      } -    return led_max < DRIVER_LED_TOTAL; +    return rgb_matrix_check_finished_leds(led_max);  }  #endif  // RGB_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c index 8f00b40877..558c7bd41a 100644 --- a/quantum/rgb_matrix/rgb_matrix.c +++ b/quantum/rgb_matrix/rgb_matrix.c @@ -31,14 +31,6 @@ const led_point_t k_rgb_matrix_center = {112, 32};  const led_point_t k_rgb_matrix_center = RGB_MATRIX_CENTER;  #endif -// clang-format off -#ifndef RGB_MATRIX_IMMEDIATE_EEPROM -#    define rgb_eeconfig_update(v) rgb_update_eeprom |= v -#else -#    define rgb_eeconfig_update(v) if (v) eeconfig_update_rgb_matrix() -#endif -// clang-format on -  __attribute__((weak)) RGB rgb_matrix_hsv_to_rgb(HSV hsv) { return hsv_to_rgb(hsv); }  // Generic effect runners @@ -128,7 +120,6 @@ last_hit_t g_last_hit_tracker;  // internals  static bool            suspend_state     = false; -static bool            rgb_update_eeprom = false;  static uint8_t         rgb_last_enable   = UINT8_MAX;  static uint8_t         rgb_last_effect   = UINT8_MAX;  static effect_params_t rgb_effect_params = {0, LED_FLAG_ALL, false}; @@ -148,9 +139,9 @@ static last_hit_t last_hit_buffer;  const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT;  #endif -void eeconfig_read_rgb_matrix(void) { eeprom_read_block(&rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_matrix_config)); } +EECONFIG_DEBOUNCE_HELPER(rgb_matrix, EECONFIG_RGB_MATRIX, rgb_matrix_config); -void eeconfig_update_rgb_matrix(void) { eeprom_update_block(&rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_matrix_config)); } +void eeconfig_update_rgb_matrix(void) { eeconfig_flush_rgb_matrix(true); }  void eeconfig_update_rgb_matrix_default(void) {      dprintf("eeconfig_update_rgb_matrix_default\n"); @@ -159,7 +150,7 @@ void eeconfig_update_rgb_matrix_default(void) {      rgb_matrix_config.hsv    = (HSV){RGB_MATRIX_STARTUP_HUE, RGB_MATRIX_STARTUP_SAT, RGB_MATRIX_STARTUP_VAL};      rgb_matrix_config.speed  = RGB_MATRIX_STARTUP_SPD;      rgb_matrix_config.flags  = LED_FLAG_ALL; -    eeconfig_update_rgb_matrix(); +    eeconfig_flush_rgb_matrix(true);  }  void eeconfig_debug_rgb_matrix(void) { @@ -187,14 +178,7 @@ uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *l  void rgb_matrix_update_pwm_buffers(void) { rgb_matrix_driver.flush(); } -void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { -#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) -    if (!is_keyboard_left() && index >= k_rgb_matrix_split[0]) -        rgb_matrix_driver.set_color(index - k_rgb_matrix_split[0], red, green, blue); -    else if (is_keyboard_left() && index < k_rgb_matrix_split[0]) -#endif -        rgb_matrix_driver.set_color(index, red, green, blue); -} +void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { rgb_matrix_driver.set_color(index, red, green, blue); }  void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {  #if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) @@ -314,9 +298,8 @@ static void rgb_task_timers(void) {  }  static void rgb_task_sync(void) { +    eeconfig_flush_rgb_matrix(false);      // next task -    if (rgb_update_eeprom) eeconfig_update_rgb_matrix(); -    rgb_update_eeprom = false;      if (sync_timer_elapsed32(g_rgb_timer) >= RGB_MATRIX_LED_FLUSH_LIMIT) rgb_task_state = STARTING;  } @@ -491,7 +474,7 @@ void rgb_matrix_init(void) {          eeconfig_update_rgb_matrix_default();      } -    eeconfig_read_rgb_matrix(); +    eeconfig_init_rgb_matrix();      if (!rgb_matrix_config.mode) {          dprintf("rgb_matrix_init_drivers rgb_matrix_config.mode = 0. Write default values to EEPROM.\n");          eeconfig_update_rgb_matrix_default(); @@ -514,7 +497,7 @@ bool rgb_matrix_get_suspend_state(void) { return suspend_state; }  void rgb_matrix_toggle_eeprom_helper(bool write_to_eeprom) {      rgb_matrix_config.enable ^= 1;      rgb_task_state = STARTING; -    rgb_eeconfig_update(write_to_eeprom); +    eeconfig_flag_rgb_matrix(write_to_eeprom);      dprintf("rgb matrix toggle [%s]: rgb_matrix_config.enable = %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.enable);  }  void rgb_matrix_toggle_noeeprom(void) { rgb_matrix_toggle_eeprom_helper(false); } @@ -522,7 +505,7 @@ void rgb_matrix_toggle(void) { rgb_matrix_toggle_eeprom_helper(true); }  void rgb_matrix_enable(void) {      rgb_matrix_enable_noeeprom(); -    rgb_eeconfig_update(true); +    eeconfig_flag_rgb_matrix(true);  }  void rgb_matrix_enable_noeeprom(void) { @@ -532,7 +515,7 @@ void rgb_matrix_enable_noeeprom(void) {  void rgb_matrix_disable(void) {      rgb_matrix_disable_noeeprom(); -    rgb_eeconfig_update(true); +    eeconfig_flag_rgb_matrix(true);  }  void rgb_matrix_disable_noeeprom(void) { @@ -554,7 +537,7 @@ void rgb_matrix_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {          rgb_matrix_config.mode = mode;      }      rgb_task_state = STARTING; -    rgb_eeconfig_update(write_to_eeprom); +    eeconfig_flag_rgb_matrix(write_to_eeprom);      dprintf("rgb matrix mode [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.mode);  }  void rgb_matrix_mode_noeeprom(uint8_t mode) { rgb_matrix_mode_eeprom_helper(mode, false); } @@ -583,7 +566,7 @@ void rgb_matrix_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, boo      rgb_matrix_config.hsv.h = hue;      rgb_matrix_config.hsv.s = sat;      rgb_matrix_config.hsv.v = (val > RGB_MATRIX_MAXIMUM_BRIGHTNESS) ? RGB_MATRIX_MAXIMUM_BRIGHTNESS : val; -    rgb_eeconfig_update(write_to_eeprom); +    eeconfig_flag_rgb_matrix(write_to_eeprom);      dprintf("rgb matrix set hsv [%s]: %u,%u,%u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.hsv.h, rgb_matrix_config.hsv.s, rgb_matrix_config.hsv.v);  }  void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) { rgb_matrix_sethsv_eeprom_helper(hue, sat, val, false); } @@ -620,7 +603,7 @@ void rgb_matrix_decrease_val(void) { rgb_matrix_decrease_val_helper(true); }  void rgb_matrix_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) {      rgb_matrix_config.speed = speed; -    rgb_eeconfig_update(write_to_eeprom); +    eeconfig_flag_rgb_matrix(write_to_eeprom);      dprintf("rgb matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.speed);  }  void rgb_matrix_set_speed_noeeprom(uint8_t speed) { rgb_matrix_set_speed_eeprom_helper(speed, false); } diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h index f53e011c1b..af5ca9e791 100644 --- a/quantum/rgb_matrix/rgb_matrix.h +++ b/quantum/rgb_matrix/rgb_matrix.h @@ -33,6 +33,8 @@  #    include "is31fl3737.h"  #elif defined(IS31FL3741)  #    include "is31fl3741.h" +#elif defined(CKLED2001) +#    include "ckled2001.h"  #elif defined(AW20216)  #    include "aw20216.h"  #elif defined(WS2812) @@ -48,14 +50,33 @@  #endif  #if defined(RGB_MATRIX_LED_PROCESS_LIMIT) && RGB_MATRIX_LED_PROCESS_LIMIT > 0 && RGB_MATRIX_LED_PROCESS_LIMIT < DRIVER_LED_TOTAL -#    define RGB_MATRIX_USE_LIMITS(min, max)                        \ -        uint8_t min = RGB_MATRIX_LED_PROCESS_LIMIT * params->iter; \ -        uint8_t max = min + RGB_MATRIX_LED_PROCESS_LIMIT;          \ -        if (max > DRIVER_LED_TOTAL) max = DRIVER_LED_TOTAL; +#    if defined(RGB_MATRIX_SPLIT) +#        define RGB_MATRIX_USE_LIMITS(min, max)                                                   \ +            uint8_t min = RGB_MATRIX_LED_PROCESS_LIMIT * params->iter;                            \ +            uint8_t max = min + RGB_MATRIX_LED_PROCESS_LIMIT;                                     \ +            if (max > DRIVER_LED_TOTAL) max = DRIVER_LED_TOTAL;                                   \ +            uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT;                                     \ +            if (is_keyboard_left() && (max > k_rgb_matrix_split[0])) max = k_rgb_matrix_split[0]; \ +            if (!(is_keyboard_left()) && (min < k_rgb_matrix_split[0])) min = k_rgb_matrix_split[0]; +#    else +#        define RGB_MATRIX_USE_LIMITS(min, max)                        \ +            uint8_t min = RGB_MATRIX_LED_PROCESS_LIMIT * params->iter; \ +            uint8_t max = min + RGB_MATRIX_LED_PROCESS_LIMIT;          \ +            if (max > DRIVER_LED_TOTAL) max = DRIVER_LED_TOTAL; +#    endif  #else -#    define RGB_MATRIX_USE_LIMITS(min, max) \ -        uint8_t min = 0;                    \ -        uint8_t max = DRIVER_LED_TOTAL; +#    if defined(RGB_MATRIX_SPLIT) +#        define RGB_MATRIX_USE_LIMITS(min, max)                                                   \ +            uint8_t       min                   = 0;                                              \ +            uint8_t       max                   = DRIVER_LED_TOTAL;                               \ +            const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT;                               \ +            if (is_keyboard_left() && (max > k_rgb_matrix_split[0])) max = k_rgb_matrix_split[0]; \ +            if (!(is_keyboard_left()) && (min < k_rgb_matrix_split[0])) min = k_rgb_matrix_split[0]; +#    else +#        define RGB_MATRIX_USE_LIMITS(min, max) \ +            uint8_t min = 0;                    \ +            uint8_t max = DRIVER_LED_TOTAL; +#    endif  #endif  #define RGB_MATRIX_INDICATOR_SET_COLOR(i, r, g, b) \ @@ -214,6 +235,18 @@ typedef struct {      void (*flush)(void);  } rgb_matrix_driver_t; +static inline bool rgb_matrix_check_finished_leds(uint8_t led_idx) { +#if defined(RGB_MATRIX_SPLIT) +    if (is_keyboard_left()) { +        uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT; +        return led_idx < k_rgb_matrix_split[0]; +    } else +        return led_idx < DRIVER_LED_TOTAL; +#else +    return led_idx < DRIVER_LED_TOTAL; +#endif +} +  extern const rgb_matrix_driver_t rgb_matrix_driver;  extern rgb_config_t rgb_matrix_config; diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c index 2cec162e22..130ca47a63 100644 --- a/quantum/rgb_matrix/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix/rgb_matrix_drivers.c @@ -23,111 +23,153 @@   * be here if shared between boards.   */ -#if defined(IS31FL3731) || defined(IS31FL3733) || defined(IS31FL3737) || defined(IS31FL3741) - +#if defined(IS31FL3731) || defined(IS31FL3733) || defined(IS31FL3737) || defined(IS31FL3741) || defined(CKLED2001)  #    include "i2c_master.h" +// TODO: Remove this at some later date +#    if defined(DRIVER_ADDR_1) && defined(DRIVER_ADDR_2) +#        if DRIVER_ADDR_1 == DRIVER_ADDR_2 +#            error "Setting DRIVER_ADDR_2 == DRIVER_ADDR_1 is obsolete. If you are only using one ISSI driver, set DRIVER_COUNT to 1 and remove DRIVER_ADDR_2" +#        endif +#    endif +  static void init(void) {      i2c_init(); -#    ifdef IS31FL3731 + +#    if defined(IS31FL3731)      IS31FL3731_init(DRIVER_ADDR_1); -#        ifdef DRIVER_ADDR_2 +#        if defined(DRIVER_ADDR_2)      IS31FL3731_init(DRIVER_ADDR_2); -#        endif -#        ifdef DRIVER_ADDR_3 +#            if defined(DRIVER_ADDR_3)      IS31FL3731_init(DRIVER_ADDR_3); -#        endif -#        ifdef DRIVER_ADDR_4 +#                if defined(DRIVER_ADDR_4)      IS31FL3731_init(DRIVER_ADDR_4); +#                endif +#            endif  #        endif +  #    elif defined(IS31FL3733) -#        ifndef DRIVER_SYNC_1 +#        if !defined(DRIVER_SYNC_1)  #            define DRIVER_SYNC_1 0  #        endif      IS31FL3733_init(DRIVER_ADDR_1, DRIVER_SYNC_1); -#        if defined DRIVER_ADDR_2 && (DRIVER_ADDR_1 != DRIVER_ADDR_2) -#            ifndef DRIVER_SYNC_2 +#        if defined(DRIVER_ADDR_2) +#            if !defined(DRIVER_SYNC_2)  #                define DRIVER_SYNC_2 0  #            endif      IS31FL3733_init(DRIVER_ADDR_2, DRIVER_SYNC_2); -#        endif -#        ifdef DRIVER_ADDR_3 -#            ifndef DRIVER_SYNC_3 -#                define DRIVER_SYNC_3 0 -#            endif +#            if defined(DRIVER_ADDR_3) +#                if !defined(DRIVER_SYNC_3) +#                    define DRIVER_SYNC_3 0 +#                endif      IS31FL3733_init(DRIVER_ADDR_3, DRIVER_SYNC_3); -#        endif -#        ifdef DRIVER_ADDR_4 -#            ifndef DRIVER_SYNC_4 -#                define DRIVER_SYNC_4 0 -#            endif +#                if defined(DRIVER_ADDR_4) +#                    if !defined(DRIVER_SYNC_4) +#                        define DRIVER_SYNC_4 0 +#                    endif      IS31FL3733_init(DRIVER_ADDR_4, DRIVER_SYNC_4); +#                endif +#            endif  #        endif +  #    elif defined(IS31FL3737)      IS31FL3737_init(DRIVER_ADDR_1); -#        if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1)  // provides backward compatibility +#        if defined(DRIVER_ADDR_2)      IS31FL3737_init(DRIVER_ADDR_2);  #        endif -#    else + +#    elif defined(IS31FL3741)      IS31FL3741_init(DRIVER_ADDR_1); + +#    elif defined(CKLED2001) +    CKLED2001_init(DRIVER_ADDR_1); +#        if defined(DRIVER_ADDR_2) +    CKLED2001_init(DRIVER_ADDR_2); +#            if defined(DRIVER_ADDR_3) +    CKLED2001_init(DRIVER_ADDR_3); +#                if defined(DRIVER_ADDR_4) +    CKLED2001_init(DRIVER_ADDR_4); +#                endif +#            endif +#        endif  #    endif +      for (int index = 0; index < DRIVER_LED_TOTAL; index++) {          bool enabled = true; +          // This only caches it for later -#    ifdef IS31FL3731 +#    if defined(IS31FL3731)          IS31FL3731_set_led_control_register(index, enabled, enabled, enabled);  #    elif defined(IS31FL3733)          IS31FL3733_set_led_control_register(index, enabled, enabled, enabled);  #    elif defined(IS31FL3737)          IS31FL3737_set_led_control_register(index, enabled, enabled, enabled); -#    else +#    elif defined(IS31FL3741)          IS31FL3741_set_led_control_register(index, enabled, enabled, enabled); +#    elif defined(CKLED2001) +        CKLED2001_set_led_control_register(index, enabled, enabled, enabled);  #    endif      } +      // This actually updates the LED drivers -#    ifdef IS31FL3731 +#    if defined(IS31FL3731)      IS31FL3731_update_led_control_registers(DRIVER_ADDR_1, 0); -#        ifdef DRIVER_ADDR_2 +#        if defined(DRIVER_ADDR_2)      IS31FL3731_update_led_control_registers(DRIVER_ADDR_2, 1); -#        endif -#        ifdef DRIVER_ADDR_3 +#            if defined(DRIVER_ADDR_3)      IS31FL3731_update_led_control_registers(DRIVER_ADDR_3, 2); -#        endif -#        ifdef DRIVER_ADDR_4 +#                if defined(DRIVER_ADDR_4)      IS31FL3731_update_led_control_registers(DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif +  #    elif defined(IS31FL3733)      IS31FL3733_update_led_control_registers(DRIVER_ADDR_1, 0); -#        ifdef DRIVER_ADDR_2 +#        if defined(DRIVER_ADDR_2)      IS31FL3733_update_led_control_registers(DRIVER_ADDR_2, 1); -#        endif -#        ifdef DRIVER_ADDR_3 +#            if defined(DRIVER_ADDR_3)      IS31FL3733_update_led_control_registers(DRIVER_ADDR_3, 2); -#        endif -#        ifdef DRIVER_ADDR_4 +#                if defined(DRIVER_ADDR_4)      IS31FL3733_update_led_control_registers(DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif +  #    elif defined(IS31FL3737)      IS31FL3737_update_led_control_registers(DRIVER_ADDR_1, 0); -#        if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1)  // provides backward compatibility +#        if defined(DRIVER_ADDR_2)      IS31FL3737_update_led_control_registers(DRIVER_ADDR_2, 1);  #        endif -#    else + +#    elif defined(IS31FL3741)      IS31FL3741_update_led_control_registers(DRIVER_ADDR_1, 0); + +#    elif defined(CKLED2001) +    CKLED2001_update_led_control_registers(DRIVER_ADDR_1, 0); +#        if defined(DRIVER_ADDR_2) +    CKLED2001_update_led_control_registers(DRIVER_ADDR_2, 1); +#            if defined(DRIVER_ADDR_3) +    CKLED2001_update_led_control_registers(DRIVER_ADDR_3, 2); +#                if defined(DRIVER_ADDR_4) +    CKLED2001_update_led_control_registers(DRIVER_ADDR_4, 3); +#                endif +#            endif +#        endif  #    endif  } -#    ifdef IS31FL3731 +#    if defined(IS31FL3731)  static void flush(void) {      IS31FL3731_update_pwm_buffers(DRIVER_ADDR_1, 0); -#        ifdef DRIVER_ADDR_2 +#        if defined(DRIVER_ADDR_2)      IS31FL3731_update_pwm_buffers(DRIVER_ADDR_2, 1); -#        endif -#        ifdef DRIVER_ADDR_3 +#            if defined(DRIVER_ADDR_3)      IS31FL3731_update_pwm_buffers(DRIVER_ADDR_3, 2); -#        endif -#        ifdef DRIVER_ADDR_4 +#                if defined(DRIVER_ADDR_4)      IS31FL3731_update_pwm_buffers(DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif  } @@ -137,17 +179,18 @@ const rgb_matrix_driver_t rgb_matrix_driver = {      .set_color     = IS31FL3731_set_color,      .set_color_all = IS31FL3731_set_color_all,  }; +  #    elif defined(IS31FL3733)  static void flush(void) {      IS31FL3733_update_pwm_buffers(DRIVER_ADDR_1, 0); -#        ifdef DRIVER_ADDR_2 +#        if defined(DRIVER_ADDR_2)      IS31FL3733_update_pwm_buffers(DRIVER_ADDR_2, 1); -#        endif -#        ifdef DRIVER_ADDR_3 +#            if defined(DRIVER_ADDR_3)      IS31FL3733_update_pwm_buffers(DRIVER_ADDR_3, 2); -#        endif -#        ifdef DRIVER_ADDR_4 +#                if defined(DRIVER_ADDR_4)      IS31FL3733_update_pwm_buffers(DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif  } @@ -157,10 +200,11 @@ const rgb_matrix_driver_t rgb_matrix_driver = {      .set_color = IS31FL3733_set_color,      .set_color_all = IS31FL3733_set_color_all,  }; +  #    elif defined(IS31FL3737)  static void flush(void) {      IS31FL3737_update_pwm_buffers(DRIVER_ADDR_1, 0); -#        if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1)  // provides backward compatibility +#        if defined(DRIVER_ADDR_2)      IS31FL3737_update_pwm_buffers(DRIVER_ADDR_2, 1);  #        endif  } @@ -171,10 +215,11 @@ const rgb_matrix_driver_t rgb_matrix_driver = {      .set_color = IS31FL3737_set_color,      .set_color_all = IS31FL3737_set_color_all,  }; -#    else + +#    elif defined(IS31FL3741)  static void flush(void) {      IS31FL3741_update_pwm_buffers(DRIVER_ADDR_1, 0); -#        if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1)  // provides backward compatibility +#        if defined(DRIVER_ADDR_2)      IS31FL3741_update_pwm_buffers(DRIVER_ADDR_2, 1);  #        endif  } @@ -185,21 +230,44 @@ const rgb_matrix_driver_t rgb_matrix_driver = {      .set_color = IS31FL3741_set_color,      .set_color_all = IS31FL3741_set_color_all,  }; + +#    elif defined(CKLED2001) +static void flush(void) { +    CKLED2001_update_pwm_buffers(DRIVER_ADDR_1, 0); +#        if defined(DRIVER_ADDR_2) +    CKLED2001_update_pwm_buffers(DRIVER_ADDR_2, 1); +#            if defined(DRIVER_ADDR_3) +    CKLED2001_update_pwm_buffers(DRIVER_ADDR_3, 2); +#                if defined(DRIVER_ADDR_4) +    CKLED2001_update_pwm_buffers(DRIVER_ADDR_4, 3); +#                endif +#            endif +#        endif +} + +const rgb_matrix_driver_t rgb_matrix_driver = { +    .init = init, +    .flush = flush, +    .set_color = CKLED2001_set_color, +    .set_color_all = CKLED2001_set_color_all, +};  #    endif  #elif defined(AW20216)  #    include "spi_master.h" +  static void init(void) {      spi_init(); +      AW20216_init(DRIVER_1_CS, DRIVER_1_EN); -#    ifdef DRIVER_2_CS +#    if defined(DRIVER_2_CS)      AW20216_init(DRIVER_2_CS, DRIVER_2_EN);  #    endif  }  static void flush(void) {      AW20216_update_pwm_buffers(DRIVER_1_CS, 0); -#    ifdef DRIVER_2_CS +#    if defined(DRIVER_2_CS)      AW20216_update_pwm_buffers(DRIVER_2_CS, 1);  #    endif  } @@ -229,6 +297,14 @@ static void flush(void) {  // Set an led in the buffer to a color  static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) { +#    if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) +    const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT; +    if (!is_keyboard_left() && (i >= k_rgb_matrix_split[0])) { +        i -= k_rgb_matrix_split[0]; +    } else if (is_keyboard_left() && (i >= k_rgb_matrix_split[0])) +        return; +#    endif +      rgb_matrix_ws2812_array[i].r = r;      rgb_matrix_ws2812_array[i].g = g;      rgb_matrix_ws2812_array[i].b = b; diff --git a/quantum/sequencer/tests/rules.mk b/quantum/sequencer/tests/rules.mk index 76c221cf92..87a204669c 100644 --- a/quantum/sequencer/tests/rules.mk +++ b/quantum/sequencer/tests/rules.mk @@ -1,5 +1,5 @@  # The letter case of these variables might seem odd. However: -# - it is consistent with the serial_link example that is used as a reference in the Unit Testing article (https://docs.qmk.fm/#/unit_testing?id=adding-tests-for-new-or-existing-features) +# - it is consistent with the example that is used as a reference in the Unit Testing article (https://docs.qmk.fm/#/unit_testing?id=adding-tests-for-new-or-existing-features)  # - Neither `make test:sequencer` or `make test:SEQUENCER` work when using SCREAMING_SNAKE_CASE  sequencer_DEFS := -DNO_DEBUG -DMIDI_MOCKED diff --git a/quantum/serial_link/LICENSE b/quantum/serial_link/LICENSE deleted file mode 100644 index d13cc4b26a..0000000000 --- a/quantum/serial_link/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -The MIT License (MIT) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/quantum/serial_link/README.md b/quantum/serial_link/README.md deleted file mode 100644 index 05871dbdf7..0000000000 --- a/quantum/serial_link/README.md +++ /dev/null @@ -1 +0,0 @@ -# qmk_serial_link diff --git a/quantum/serial_link/protocol/byte_stuffer.c b/quantum/serial_link/protocol/byte_stuffer.c deleted file mode 100644 index d3a91d8286..0000000000 --- a/quantum/serial_link/protocol/byte_stuffer.c +++ /dev/null @@ -1,135 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/frame_validator.h" -#include "serial_link/protocol/physical.h" -#include <stdbool.h> - -// This implements the "Consistent overhead byte stuffing protocol" -// https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing -// http://www.stuartcheshire.org/papers/COBSforToN.pdf - -typedef struct byte_stuffer_state { -    uint16_t next_zero; -    uint16_t data_pos; -    bool     long_frame; -    uint8_t  data[MAX_FRAME_SIZE]; -} byte_stuffer_state_t; - -static byte_stuffer_state_t states[NUM_LINKS]; - -void init_byte_stuffer_state(byte_stuffer_state_t* state) { -    state->next_zero  = 0; -    state->data_pos   = 0; -    state->long_frame = false; -} - -void init_byte_stuffer(void) { -    int i; -    for (i = 0; i < NUM_LINKS; i++) { -        init_byte_stuffer_state(&states[i]); -    } -} - -void byte_stuffer_recv_byte(uint8_t link, uint8_t data) { -    byte_stuffer_state_t* state = &states[link]; -    // Start of a new frame -    if (state->next_zero == 0) { -        state->next_zero  = data; -        state->long_frame = data == 0xFF; -        state->data_pos   = 0; -        return; -    } - -    state->next_zero--; -    if (data == 0) { -        if (state->next_zero == 0) { -            // The frame is completed -            if (state->data_pos > 0) { -                validator_recv_frame(link, state->data, state->data_pos); -            } -        } else { -            // The frame is invalid, so reset -            init_byte_stuffer_state(state); -        } -    } else { -        if (state->data_pos == MAX_FRAME_SIZE) { -            // We exceeded our maximum frame size -            // therefore there's nothing else to do than reset to a new frame -            state->next_zero  = data; -            state->long_frame = data == 0xFF; -            state->data_pos   = 0; -        } else if (state->next_zero == 0) { -            if (state->long_frame) { -                // This is part of a long frame, so continue -                state->next_zero  = data; -                state->long_frame = data == 0xFF; -            } else { -                // Special case for zeroes -                state->next_zero               = data; -                state->data[state->data_pos++] = 0; -            } -        } else { -            state->data[state->data_pos++] = data; -        } -    } -} - -static void send_block(uint8_t link, uint8_t* start, uint8_t* end, uint8_t num_non_zero) { -    send_data(link, &num_non_zero, 1); -    if (end > start) { -        send_data(link, start, end - start); -    } -} - -void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { -    const uint8_t zero = 0; -    if (size > 0) { -        uint16_t num_non_zero = 1; -        uint8_t* end          = data + size; -        uint8_t* start        = data; -        while (data < end) { -            if (num_non_zero == 0xFF) { -                // There's more data after big non-zero block -                // So send it, and start a new block -                send_block(link, start, data, num_non_zero); -                start        = data; -                num_non_zero = 1; -            } else { -                if (*data == 0) { -                    // A zero encountered, so send the block -                    send_block(link, start, data, num_non_zero); -                    start        = data + 1; -                    num_non_zero = 1; -                } else { -                    num_non_zero++; -                } -                ++data; -            } -        } -        send_block(link, start, data, num_non_zero); -        send_data(link, &zero, 1); -    } -} diff --git a/quantum/serial_link/protocol/byte_stuffer.h b/quantum/serial_link/protocol/byte_stuffer.h deleted file mode 100644 index 397ed3baae..0000000000 --- a/quantum/serial_link/protocol/byte_stuffer.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -#include <stdint.h> - -#define MAX_FRAME_SIZE 1024 -#define NUM_LINKS 2 - -void init_byte_stuffer(void); -void byte_stuffer_recv_byte(uint8_t link, uint8_t data); -void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size); diff --git a/quantum/serial_link/protocol/frame_router.c b/quantum/serial_link/protocol/frame_router.c deleted file mode 100644 index 5292673700..0000000000 --- a/quantum/serial_link/protocol/frame_router.c +++ /dev/null @@ -1,64 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/frame_router.h" -#include "serial_link/protocol/transport.h" -#include "serial_link/protocol/frame_validator.h" - -static bool is_master; - -void router_set_master(bool master) { is_master = master; } - -void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size) { -    if (is_master) { -        if (link == DOWN_LINK) { -            transport_recv_frame(data[size - 1], data, size - 1); -        } -    } else { -        if (link == UP_LINK) { -            if (data[size - 1] & 1) { -                transport_recv_frame(0, data, size - 1); -            } -            data[size - 1] >>= 1; -            validator_send_frame(DOWN_LINK, data, size); -        } else { -            data[size - 1]++; -            validator_send_frame(UP_LINK, data, size); -        } -    } -} - -void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { -    if (destination == 0) { -        if (!is_master) { -            data[size] = 1; -            validator_send_frame(UP_LINK, data, size + 1); -        } -    } else { -        if (is_master) { -            data[size] = destination; -            validator_send_frame(DOWN_LINK, data, size + 1); -        } -    } -} diff --git a/quantum/serial_link/protocol/frame_router.h b/quantum/serial_link/protocol/frame_router.h deleted file mode 100644 index 9325fe4eed..0000000000 --- a/quantum/serial_link/protocol/frame_router.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -#include <stdint.h> -#include <stdbool.h> - -#define UP_LINK 0 -#define DOWN_LINK 1 - -void router_set_master(bool master); -void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size); -void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size); diff --git a/quantum/serial_link/protocol/frame_validator.c b/quantum/serial_link/protocol/frame_validator.c deleted file mode 100644 index bc9136f70b..0000000000 --- a/quantum/serial_link/protocol/frame_validator.c +++ /dev/null @@ -1,57 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/frame_validator.h" -#include "serial_link/protocol/frame_router.h" -#include "serial_link/protocol/byte_stuffer.h" -#include <string.h> - -const uint32_t poly8_lookup[256] = {0,          0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, -                                    0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, -                                    0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, -                                    0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D}; - -static uint32_t crc32_byte(uint8_t* p, uint32_t bytelength) { -    uint32_t crc = 0xffffffff; -    while (bytelength-- != 0) crc = poly8_lookup[((uint8_t)crc ^ *(p++))] ^ (crc >> 8); -    // return (~crc); also works -    return (crc ^ 0xffffffff); -} - -void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { -    if (size > 4) { -        uint32_t frame_crc; -        memcpy(&frame_crc, data + size - 4, 4); -        uint32_t expected_crc = crc32_byte(data, size - 4); -        if (frame_crc == expected_crc) { -            route_incoming_frame(link, data, size - 4); -        } -    } -} - -void validator_send_frame(uint8_t link, uint8_t* data, uint16_t size) { -    uint32_t crc = crc32_byte(data, size); -    memcpy(data + size, &crc, 4); -    byte_stuffer_send_frame(link, data, size + 4); -} diff --git a/quantum/serial_link/protocol/frame_validator.h b/quantum/serial_link/protocol/frame_validator.h deleted file mode 100644 index 0f78768a00..0000000000 --- a/quantum/serial_link/protocol/frame_validator.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -#include <stdint.h> - -void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size); -// The buffer pointed to by the data needs 4 additional bytes -void validator_send_frame(uint8_t link, uint8_t* data, uint16_t size); diff --git a/quantum/serial_link/protocol/physical.h b/quantum/serial_link/protocol/physical.h deleted file mode 100644 index 399c9d1f76..0000000000 --- a/quantum/serial_link/protocol/physical.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -void send_data(uint8_t link, const uint8_t* data, uint16_t size); diff --git a/quantum/serial_link/protocol/transport.c b/quantum/serial_link/protocol/transport.c deleted file mode 100644 index 73b8dc62e9..0000000000 --- a/quantum/serial_link/protocol/transport.c +++ /dev/null @@ -1,121 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/transport.h" -#include "serial_link/protocol/frame_router.h" -#include "serial_link/protocol/triple_buffered_object.h" -#include <string.h> - -#define MAX_REMOTE_OBJECTS 16 -static remote_object_t* remote_objects[MAX_REMOTE_OBJECTS]; -static uint32_t         num_remote_objects = 0; - -void reinitialize_serial_link_transport(void) { num_remote_objects = 0; } - -void add_remote_objects(remote_object_t** _remote_objects, uint32_t _num_remote_objects) { -    unsigned int i; -    for (i = 0; i < _num_remote_objects; i++) { -        remote_object_t* obj                 = _remote_objects[i]; -        remote_objects[num_remote_objects++] = obj; -        if (obj->object_type == MASTER_TO_ALL_SLAVES) { -            triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; -            triple_buffer_init(tb); -            uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); -            tb             = (triple_buffer_object_t*)start; -            triple_buffer_init(tb); -        } else if (obj->object_type == MASTER_TO_SINGLE_SLAVE) { -            uint8_t*     start = obj->buffer; -            unsigned int j; -            for (j = 0; j < NUM_SLAVES; j++) { -                triple_buffer_object_t* tb = (triple_buffer_object_t*)start; -                triple_buffer_init(tb); -                start += LOCAL_OBJECT_SIZE(obj->object_size); -            } -            triple_buffer_object_t* tb = (triple_buffer_object_t*)start; -            triple_buffer_init(tb); -        } else { -            uint8_t*                start = obj->buffer; -            triple_buffer_object_t* tb    = (triple_buffer_object_t*)start; -            triple_buffer_init(tb); -            start += LOCAL_OBJECT_SIZE(obj->object_size); -            unsigned int j; -            for (j = 0; j < NUM_SLAVES; j++) { -                tb = (triple_buffer_object_t*)start; -                triple_buffer_init(tb); -                start += REMOTE_OBJECT_SIZE(obj->object_size); -            } -        } -    } -} - -void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { -    uint8_t id = data[size - 1]; -    if (id < num_remote_objects) { -        remote_object_t* obj = remote_objects[id]; -        if (obj->object_size == size - 1) { -            uint8_t* start; -            if (obj->object_type == MASTER_TO_ALL_SLAVES) { -                start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); -            } else if (obj->object_type == SLAVE_TO_MASTER) { -                start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); -                start += (from - 1) * REMOTE_OBJECT_SIZE(obj->object_size); -            } else { -                start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size); -            } -            triple_buffer_object_t* tb  = (triple_buffer_object_t*)start; -            void*                   ptr = triple_buffer_begin_write_internal(obj->object_size, tb); -            memcpy(ptr, data, size - 1); -            triple_buffer_end_write_internal(tb); -        } -    } -} - -void update_transport(void) { -    unsigned int i; -    for (i = 0; i < num_remote_objects; i++) { -        remote_object_t* obj = remote_objects[i]; -        if (obj->object_type == MASTER_TO_ALL_SLAVES || obj->object_type == SLAVE_TO_MASTER) { -            triple_buffer_object_t* tb  = (triple_buffer_object_t*)obj->buffer; -            uint8_t*                ptr = (uint8_t*)triple_buffer_read_internal(obj->object_size + LOCAL_OBJECT_EXTRA, tb); -            if (ptr) { -                ptr[obj->object_size] = i; -                uint8_t dest          = obj->object_type == MASTER_TO_ALL_SLAVES ? 0xFF : 0; -                router_send_frame(dest, ptr, obj->object_size + 1); -            } -        } else { -            uint8_t*     start = obj->buffer; -            unsigned int j; -            for (j = 0; j < NUM_SLAVES; j++) { -                triple_buffer_object_t* tb  = (triple_buffer_object_t*)start; -                uint8_t*                ptr = (uint8_t*)triple_buffer_read_internal(obj->object_size + LOCAL_OBJECT_EXTRA, tb); -                if (ptr) { -                    ptr[obj->object_size] = i; -                    uint8_t dest          = j + 1; -                    router_send_frame(dest, ptr, obj->object_size + 1); -                } -                start += LOCAL_OBJECT_SIZE(obj->object_size); -            } -        } -    } -} diff --git a/quantum/serial_link/protocol/transport.h b/quantum/serial_link/protocol/transport.h deleted file mode 100644 index 3ce0c9fe4e..0000000000 --- a/quantum/serial_link/protocol/transport.h +++ /dev/null @@ -1,139 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -#include "serial_link/protocol/triple_buffered_object.h" -#include "serial_link/system/serial_link.h" - -#define NUM_SLAVES 8 -#define LOCAL_OBJECT_EXTRA 16 - -// master -> slave = 1 local(target all), 1 remote object -// slave -> master = 1 local(target 0), multiple remote objects -// master -> single slave (multiple local, target id), 1 remote object -typedef enum { -    MASTER_TO_ALL_SLAVES, -    MASTER_TO_SINGLE_SLAVE, -    SLAVE_TO_MASTER, -} remote_object_type; - -typedef struct { -    remote_object_type object_type; -    uint16_t           object_size; -    uint8_t            buffer[] __attribute__((aligned(4))); -} remote_object_t; - -#define REMOTE_OBJECT_SIZE(objectsize) (sizeof(triple_buffer_object_t) + objectsize * 3) -#define LOCAL_OBJECT_SIZE(objectsize) (sizeof(triple_buffer_object_t) + (objectsize + LOCAL_OBJECT_EXTRA) * 3) - -#define REMOTE_OBJECT_HELPER(name, type, num_local, num_remote)                                                              \ -    typedef struct {                                                                                                         \ -        remote_object_t object;                                                                                              \ -        uint8_t         buffer[num_remote * REMOTE_OBJECT_SIZE(sizeof(type)) + num_local * LOCAL_OBJECT_SIZE(sizeof(type))]; \ -    } remote_object_##name##_t; - -#define MASTER_TO_ALL_SLAVES_OBJECT(name, type)                                                                     \ -    REMOTE_OBJECT_HELPER(name, type, 1, 1)                                                                          \ -    remote_object_##name##_t remote_object_##name = {.object = {                                                    \ -                                                         .object_type = MASTER_TO_ALL_SLAVES,                       \ -                                                         .object_size = sizeof(type),                               \ -                                                     }};                                                            \ -    type*                    begin_write_##name(void) {                                                             \ -        remote_object_t*        obj = (remote_object_t*)&remote_object_##name;                   \ -        triple_buffer_object_t* tb  = (triple_buffer_object_t*)obj->buffer;                      \ -        return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ -    }                                                                                                               \ -    void end_write_##name(void) {                                                                                   \ -        remote_object_t*        obj = (remote_object_t*)&remote_object_##name;                                      \ -        triple_buffer_object_t* tb  = (triple_buffer_object_t*)obj->buffer;                                         \ -        triple_buffer_end_write_internal(tb);                                                                       \ -        signal_data_written();                                                                                      \ -    }                                                                                                               \ -    type* read_##name(void) {                                                                                       \ -        remote_object_t*        obj   = (remote_object_t*)&remote_object_##name;                                    \ -        uint8_t*                start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);                          \ -        triple_buffer_object_t* tb    = (triple_buffer_object_t*)start;                                             \ -        return (type*)triple_buffer_read_internal(obj->object_size, tb);                                            \ -    } - -#define MASTER_TO_SINGLE_SLAVE_OBJECT(name, type)                                                                   \ -    REMOTE_OBJECT_HELPER(name, type, NUM_SLAVES, 1)                                                                 \ -    remote_object_##name##_t remote_object_##name = {.object = {                                                    \ -                                                         .object_type = MASTER_TO_SINGLE_SLAVE,                     \ -                                                         .object_size = sizeof(type),                               \ -                                                     }};                                                            \ -    type*                    begin_write_##name(uint8_t slave) {                                                    \ -        remote_object_t* obj   = (remote_object_t*)&remote_object_##name;                        \ -        uint8_t*         start = obj->buffer;                                                    \ -        start += slave * LOCAL_OBJECT_SIZE(obj->object_size);                                    \ -        triple_buffer_object_t* tb = (triple_buffer_object_t*)start;                             \ -        return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ -    }                                                                                                               \ -    void end_write_##name(uint8_t slave) {                                                                          \ -        remote_object_t* obj   = (remote_object_t*)&remote_object_##name;                                           \ -        uint8_t*         start = obj->buffer;                                                                       \ -        start += slave * LOCAL_OBJECT_SIZE(obj->object_size);                                                       \ -        triple_buffer_object_t* tb = (triple_buffer_object_t*)start;                                                \ -        triple_buffer_end_write_internal(tb);                                                                       \ -        signal_data_written();                                                                                      \ -    }                                                                                                               \ -    type* read_##name() {                                                                                           \ -        remote_object_t*        obj   = (remote_object_t*)&remote_object_##name;                                    \ -        uint8_t*                start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size);             \ -        triple_buffer_object_t* tb    = (triple_buffer_object_t*)start;                                             \ -        return (type*)triple_buffer_read_internal(obj->object_size, tb);                                            \ -    } - -#define SLAVE_TO_MASTER_OBJECT(name, type)                                                                          \ -    REMOTE_OBJECT_HELPER(name, type, 1, NUM_SLAVES)                                                                 \ -    remote_object_##name##_t remote_object_##name = {.object = {                                                    \ -                                                         .object_type = SLAVE_TO_MASTER,                            \ -                                                         .object_size = sizeof(type),                               \ -                                                     }};                                                            \ -    type*                    begin_write_##name(void) {                                                             \ -        remote_object_t*        obj = (remote_object_t*)&remote_object_##name;                   \ -        triple_buffer_object_t* tb  = (triple_buffer_object_t*)obj->buffer;                      \ -        return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ -    }                                                                                                               \ -    void end_write_##name(void) {                                                                                   \ -        remote_object_t*        obj = (remote_object_t*)&remote_object_##name;                                      \ -        triple_buffer_object_t* tb  = (triple_buffer_object_t*)obj->buffer;                                         \ -        triple_buffer_end_write_internal(tb);                                                                       \ -        signal_data_written();                                                                                      \ -    }                                                                                                               \ -    type* read_##name(uint8_t slave) {                                                                              \ -        remote_object_t* obj   = (remote_object_t*)&remote_object_##name;                                           \ -        uint8_t*         start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);                                 \ -        start += slave * REMOTE_OBJECT_SIZE(obj->object_size);                                                      \ -        triple_buffer_object_t* tb = (triple_buffer_object_t*)start;                                                \ -        return (type*)triple_buffer_read_internal(obj->object_size, tb);                                            \ -    } - -#define REMOTE_OBJECT(name) (remote_object_t*)&remote_object_##name - -void add_remote_objects(remote_object_t** remote_objects, uint32_t num_remote_objects); -void reinitialize_serial_link_transport(void); -void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size); -void update_transport(void); diff --git a/quantum/serial_link/protocol/triple_buffered_object.c b/quantum/serial_link/protocol/triple_buffered_object.c deleted file mode 100644 index e0c6d702a5..0000000000 --- a/quantum/serial_link/protocol/triple_buffered_object.c +++ /dev/null @@ -1,77 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "serial_link/protocol/triple_buffered_object.h" -#include "serial_link/system/serial_link.h" -#include <stdbool.h> -#include <stddef.h> - -#define GET_READ_INDEX() object->state & 3 -#define GET_WRITE_INDEX() (object->state >> 2) & 3 -#define GET_SHARED_INDEX() (object->state >> 4) & 3 -#define GET_DATA_AVAILABLE() (object->state >> 6) & 1 - -#define SET_READ_INDEX(i) object->state = ((object->state & ~3) | i) -#define SET_WRITE_INDEX(i) object->state = ((object->state & ~(3 << 2)) | (i << 2)) -#define SET_SHARED_INDEX(i) object->state = ((object->state & ~(3 << 4)) | (i << 4)) -#define SET_DATA_AVAILABLE(i) object->state = ((object->state & ~(1 << 6)) | (i << 6)) - -void triple_buffer_init(triple_buffer_object_t* object) { -    object->state = 0; -    SET_WRITE_INDEX(0); -    SET_READ_INDEX(1); -    SET_SHARED_INDEX(2); -    SET_DATA_AVAILABLE(0); -} - -void* triple_buffer_read_internal(uint16_t object_size, triple_buffer_object_t* object) { -    serial_link_lock(); -    if (GET_DATA_AVAILABLE()) { -        uint8_t shared_index = GET_SHARED_INDEX(); -        uint8_t read_index   = GET_READ_INDEX(); -        SET_READ_INDEX(shared_index); -        SET_SHARED_INDEX(read_index); -        SET_DATA_AVAILABLE(false); -        serial_link_unlock(); -        return object->buffer + object_size * shared_index; -    } else { -        serial_link_unlock(); -        return NULL; -    } -} - -void* triple_buffer_begin_write_internal(uint16_t object_size, triple_buffer_object_t* object) { -    uint8_t write_index = GET_WRITE_INDEX(); -    return object->buffer + object_size * write_index; -} - -void triple_buffer_end_write_internal(triple_buffer_object_t* object) { -    serial_link_lock(); -    uint8_t shared_index = GET_SHARED_INDEX(); -    uint8_t write_index  = GET_WRITE_INDEX(); -    SET_SHARED_INDEX(write_index); -    SET_WRITE_INDEX(shared_index); -    SET_DATA_AVAILABLE(true); -    serial_link_unlock(); -} diff --git a/quantum/serial_link/protocol/triple_buffered_object.h b/quantum/serial_link/protocol/triple_buffered_object.h deleted file mode 100644 index 717d6d7b8b..0000000000 --- a/quantum/serial_link/protocol/triple_buffered_object.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -#include <stdint.h> - -typedef struct { -    uint8_t state; -    uint8_t buffer[] __attribute__((aligned(4))); -} triple_buffer_object_t; - -void triple_buffer_init(triple_buffer_object_t* object); - -#define triple_buffer_begin_write(object) (typeof(*object.buffer[0])*)triple_buffer_begin_write_internal(sizeof(*object.buffer[0]), (triple_buffer_object_t*)object) - -#define triple_buffer_end_write(object) triple_buffer_end_write_internal((triple_buffer_object_t*)object) - -#define triple_buffer_read(object) (typeof(*object.buffer[0])*)triple_buffer_read_internal(sizeof(*object.buffer[0]), (triple_buffer_object_t*)object) - -void* triple_buffer_begin_write_internal(uint16_t object_size, triple_buffer_object_t* object); -void  triple_buffer_end_write_internal(triple_buffer_object_t* object); -void* triple_buffer_read_internal(uint16_t object_size, triple_buffer_object_t* object); diff --git a/quantum/serial_link/system/serial_link.c b/quantum/serial_link/system/serial_link.c deleted file mode 100644 index 6363f8ff3b..0000000000 --- a/quantum/serial_link/system/serial_link.c +++ /dev/null @@ -1,250 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -#include "report.h" -#include "host_driver.h" -#include "serial_link/system/serial_link.h" -#include <hal.h> -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/transport.h" -#include "serial_link/protocol/frame_router.h" -#include "matrix.h" -#include "sync_timer.h" -#include <stdbool.h> -#include "print.h" -#include "config.h" - -#define SYNC_TIMER_OFFSET 2 - -static event_source_t new_data_event; -static bool           serial_link_connected; -static bool           is_master = false; - -static uint8_t keyboard_leds(void); -static void    send_keyboard(report_keyboard_t* report); -static void    send_mouse(report_mouse_t* report); -static void    send_system(uint16_t data); -static void    send_consumer(uint16_t data); - -host_driver_t serial_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer}; - -// Define these in your Config.h file -#ifndef SERIAL_LINK_BAUD -#    error "Serial link baud is not set" -#endif - -#ifndef SERIAL_LINK_THREAD_PRIORITY -#    error "Serial link thread priority not set" -#endif - -static SerialConfig config = {.sc_speed = SERIAL_LINK_BAUD}; - -//#define DEBUG_LINK_ERRORS - -static uint32_t read_from_serial(SerialDriver* driver, uint8_t link) { -    const uint32_t buffer_size = 16; -    uint8_t        buffer[buffer_size]; -    uint32_t       bytes_read = sdAsynchronousRead(driver, buffer, buffer_size); -    uint8_t*       current    = buffer; -    uint8_t*       end        = current + bytes_read; -    while (current < end) { -        byte_stuffer_recv_byte(link, *current); -        current++; -    } -    return bytes_read; -} - -static void print_error(char* str, eventflags_t flags, SerialDriver* driver) { -#ifdef DEBUG_LINK_ERRORS -    if (flags & SD_PARITY_ERROR) { -        print(str); -        print(" Parity error\n"); -    } -    if (flags & SD_FRAMING_ERROR) { -        print(str); -        print(" Framing error\n"); -    } -    if (flags & SD_OVERRUN_ERROR) { -        print(str); -        uint32_t size = qSpaceI(&(driver->iqueue)); -        xprintf(" Overrun error, queue size %d\n", size); -    } -    if (flags & SD_NOISE_ERROR) { -        print(str); -        print(" Noise error\n"); -    } -    if (flags & SD_BREAK_DETECTED) { -        print(str); -        print(" Break detected\n"); -    } -#else -    (void)str; -    (void)flags; -    (void)driver; -#endif -} - -bool is_serial_link_master(void) { return is_master; } - -// TODO: Optimize the stack size, this is probably way too big -static THD_WORKING_AREA(serialThreadStack, 1024); -static THD_FUNCTION(serialThread, arg) { -    (void)arg; -    event_listener_t new_data_listener; -    event_listener_t sd1_listener; -    event_listener_t sd2_listener; -    chEvtRegister(&new_data_event, &new_data_listener, 0); -    eventflags_t events = CHN_INPUT_AVAILABLE | SD_PARITY_ERROR | SD_FRAMING_ERROR | SD_OVERRUN_ERROR | SD_NOISE_ERROR | SD_BREAK_DETECTED; -    chEvtRegisterMaskWithFlags(chnGetEventSource(&SD1), &sd1_listener, EVENT_MASK(1), events); -    chEvtRegisterMaskWithFlags(chnGetEventSource(&SD2), &sd2_listener, EVENT_MASK(2), events); -    bool need_wait = false; -    while (true) { -        eventflags_t flags1 = 0; -        eventflags_t flags2 = 0; -        if (need_wait) { -            eventmask_t mask = chEvtWaitAnyTimeout(ALL_EVENTS, TIME_MS2I(1000)); -            if (mask & EVENT_MASK(1)) { -                flags1 = chEvtGetAndClearFlags(&sd1_listener); -                print_error("DOWNLINK", flags1, &SD1); -            } -            if (mask & EVENT_MASK(2)) { -                flags2 = chEvtGetAndClearFlags(&sd2_listener); -                print_error("UPLINK", flags2, &SD2); -            } -        } - -        // Always stay as master, even if the USB goes into sleep mode -        is_master |= usbGetDriverStateI(&USBD1) == USB_ACTIVE; -        router_set_master(is_master); - -        need_wait = true; -        need_wait &= read_from_serial(&SD2, UP_LINK) == 0; -        need_wait &= read_from_serial(&SD1, DOWN_LINK) == 0; -        update_transport(); -    } -} - -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { -    if (link == DOWN_LINK) { -        sdWrite(&SD1, data, size); -    } else { -        sdWrite(&SD2, data, size); -    } -} - -static systime_t last_update = 0; - -typedef struct { -    matrix_row_t rows[MATRIX_ROWS]; -} matrix_object_t; - -static matrix_object_t last_matrix = {}; - -SLAVE_TO_MASTER_OBJECT(keyboard_matrix, matrix_object_t); -MASTER_TO_ALL_SLAVES_OBJECT(serial_link_connected, bool); -#ifndef DISABLE_SYNC_TIMER -MASTER_TO_ALL_SLAVES_OBJECT(sync_timer, uint32_t); -#endif - -static remote_object_t* remote_objects[] = { -    REMOTE_OBJECT(serial_link_connected), -    REMOTE_OBJECT(keyboard_matrix), -#ifndef DISABLE_SYNC_TIMER -    REMOTE_OBJECT(sync_timer), -#endif -}; - -void init_serial_link(void) { -    serial_link_connected = false; -    init_serial_link_hal(); -    add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*)); -    init_byte_stuffer(); -    sdStart(&SD1, &config); -    sdStart(&SD2, &config); -    chEvtObjectInit(&new_data_event); -    (void)chThdCreateStatic(serialThreadStack, sizeof(serialThreadStack), SERIAL_LINK_THREAD_PRIORITY, serialThread, NULL); -} - -void matrix_set_remote(matrix_row_t* rows, uint8_t index); - -void serial_link_update(void) { -    if (read_serial_link_connected()) { -        serial_link_connected = true; -    } - -    matrix_object_t matrix; -    bool            changed = false; -    for (uint8_t i = 0; i < MATRIX_ROWS; i++) { -        matrix.rows[i] = matrix_get_row(i); -        changed |= matrix.rows[i] != last_matrix.rows[i]; -    } - -    systime_t current_time = chVTGetSystemTimeX(); -    systime_t delta        = current_time - last_update; -    if (changed || delta > TIME_US2I(5000)) { -        last_update        = current_time; -        last_matrix        = matrix; -        matrix_object_t* m = begin_write_keyboard_matrix(); -        for (uint8_t i = 0; i < MATRIX_ROWS; i++) { -            m->rows[i] = matrix.rows[i]; -        } -        end_write_keyboard_matrix(); - -        *begin_write_serial_link_connected() = true; -        end_write_serial_link_connected(); - -#ifndef DISABLE_SYNC_TIMER -        *begin_write_sync_timer() = sync_timer_read32() + SYNC_TIMER_OFFSET; -        end_write_sync_timer(); -#endif -    } - -    matrix_object_t* m = read_keyboard_matrix(0); -    if (m) { -        matrix_set_remote(m->rows, 0); -    } - -#ifndef DISABLE_SYNC_TIMER -    uint32_t* t = read_sync_timer(); -    if (t) { -        sync_timer_update(*t); -    } -#endif -} - -void signal_data_written(void) { chEvtBroadcast(&new_data_event); } - -bool is_serial_link_connected(void) { return serial_link_connected; } - -host_driver_t* get_serial_link_driver(void) { return &serial_driver; } - -// NOTE: The driver does nothing, because the master handles everything -uint8_t keyboard_leds(void) { return 0; } - -void send_keyboard(report_keyboard_t* report) { (void)report; } - -void send_mouse(report_mouse_t* report) { (void)report; } - -void send_system(uint16_t data) { (void)data; } - -void send_consumer(uint16_t data) { (void)data; } diff --git a/quantum/serial_link/system/serial_link.h b/quantum/serial_link/system/serial_link.h deleted file mode 100644 index adc1f6e93d..0000000000 --- a/quantum/serial_link/system/serial_link.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -#include "host_driver.h" -#include <stdbool.h> - -void           init_serial_link(void); -void           init_serial_link_hal(void); -bool           is_serial_link_connected(void); -bool           is_serial_link_master(void); -host_driver_t* get_serial_link_driver(void); -void           serial_link_update(void); - -#if defined(PROTOCOL_CHIBIOS) -#    include <ch.h> - -static inline void serial_link_lock(void) { chSysLock(); } - -static inline void serial_link_unlock(void) { chSysUnlock(); } - -void signal_data_written(void); - -#else - -inline void serial_link_lock(void) {} - -inline void serial_link_unlock(void) {} - -void signal_data_written(void); - -#endif diff --git a/quantum/serial_link/tests/Makefile b/quantum/serial_link/tests/Makefile deleted file mode 100644 index 11dd355b22..0000000000 --- a/quantum/serial_link/tests/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2016 Fred Sundvik -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -CC = gcc -CFLAGS	= -INCLUDES = -I. -I../../ -LDFLAGS = -L$(BUILDDIR)/cgreen/build-c/src -shared -LDLIBS = -lcgreen -UNITOBJ = $(BUILDDIR)/serialtest/unitobj -DEPDIR = $(BUILDDIR)/serialtest/unit.d -UNITTESTS = $(BUILDDIR)/serialtest/unittests -DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td -EXT = .so -UNAME := $(shell uname) -ifneq (, $(findstring MINGW, $(UNAME))) -	EXT = .dll -endif -ifneq (, $(findstring CYGWIN, $(UNAME))) -	EXT = .dll -endif - -SRC = $(wildcard *.c) -TESTFILES = $(patsubst %.c, $(UNITTESTS)/%$(EXT), $(SRC)) -$(shell mkdir -p $(DEPDIR) >/dev/null) - -test: $(TESTFILES) -	@$(BUILDDIR)/cgreen/build-c/tools/cgreen-runner --color $(TESTFILES) - -$(UNITTESTS)/%$(EXT): $(UNITOBJ)/%.o -	@mkdir -p $(UNITTESTS) -	$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) - -$(UNITOBJ)/%.o : %.c -$(UNITOBJ)/%.o: %.c $(DEPDIR)/%.d -	@mkdir -p $(UNITOBJ) -	$(CC) $(CFLAGS) $(DEPFLAGS) $(INCLUDES) -c $< -o $@ -	@mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d - -$(DEPDIR)/%.d: ; -.PRECIOUS: $(DEPDIR)/%.d - --include $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRC))) diff --git a/quantum/serial_link/tests/byte_stuffer_tests.cpp b/quantum/serial_link/tests/byte_stuffer_tests.cpp deleted file mode 100644 index 9e4e1768f4..0000000000 --- a/quantum/serial_link/tests/byte_stuffer_tests.cpp +++ /dev/null @@ -1,450 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include <vector> -#include <algorithm> -extern "C" { -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/frame_validator.h" -#include "serial_link/protocol/physical.h" -} - -using testing::_; -using testing::Args; -using testing::ElementsAreArray; - -class ByteStuffer : public ::testing::Test { -   public: -    ByteStuffer() { -        Instance = this; -        init_byte_stuffer(); -    } - -    ~ByteStuffer() { Instance = nullptr; } - -    MOCK_METHOD3(validator_recv_frame, void(uint8_t link, uint8_t* data, uint16_t size)); - -    void                 send_data(uint8_t link, const uint8_t* data, uint16_t size) { std::copy(data, data + size, std::back_inserter(sent_data)); } -    std::vector<uint8_t> sent_data; - -    static ByteStuffer* Instance; -}; - -ByteStuffer* ByteStuffer::Instance = nullptr; - -extern "C" { -void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { ByteStuffer::Instance->validator_recv_frame(link, data, size); } - -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { ByteStuffer::Instance->send_data(link, data, size); } -} - -TEST_F(ByteStuffer, receives_no_frame_for_a_single_zero_byte) { -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).Times(0); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_no_frame_for_a_single_FF_byte) { -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).Times(0); -    byte_stuffer_recv_byte(0, 0xFF); -} - -TEST_F(ByteStuffer, receives_no_frame_for_a_single_random_byte) { -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).Times(0); -    byte_stuffer_recv_byte(0, 0x4A); -} - -TEST_F(ByteStuffer, receives_no_frame_for_a_zero_length_frame) { -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).Times(0); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_single_byte_valid_frame) { -    uint8_t expected[] = {0x37}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 0x37); -    byte_stuffer_recv_byte(0, 0); -} -TEST_F(ByteStuffer, receives_three_bytes_valid_frame) { -    uint8_t expected[] = {0x37, 0x99, 0xFF}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 4); -    byte_stuffer_recv_byte(0, 0x37); -    byte_stuffer_recv_byte(0, 0x99); -    byte_stuffer_recv_byte(0, 0xFF); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_single_zero_valid_frame) { -    uint8_t expected[] = {0}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_valid_frame_with_zeroes) { -    uint8_t expected[] = {5, 0, 3, 0}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 5); -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 3); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_two_valid_frames) { -    uint8_t expected1[] = {5, 0}; -    uint8_t expected2[] = {3}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected1))); -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected2))); -    byte_stuffer_recv_byte(1, 2); -    byte_stuffer_recv_byte(1, 5); -    byte_stuffer_recv_byte(1, 1); -    byte_stuffer_recv_byte(1, 0); -    byte_stuffer_recv_byte(1, 2); -    byte_stuffer_recv_byte(1, 3); -    byte_stuffer_recv_byte(1, 0); -} - -TEST_F(ByteStuffer, receives_valid_frame_after_unexpected_zero) { -    uint8_t expected[] = {5, 7}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(1, 3); -    byte_stuffer_recv_byte(1, 1); -    byte_stuffer_recv_byte(1, 0); -    byte_stuffer_recv_byte(1, 3); -    byte_stuffer_recv_byte(1, 5); -    byte_stuffer_recv_byte(1, 7); -    byte_stuffer_recv_byte(1, 0); -} - -TEST_F(ByteStuffer, receives_valid_frame_after_unexpected_non_zero) { -    uint8_t expected[] = {5, 7}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 9); -    byte_stuffer_recv_byte(0, 4);  // This should have been zero -    byte_stuffer_recv_byte(0, 0); -    byte_stuffer_recv_byte(0, 3); -    byte_stuffer_recv_byte(0, 5); -    byte_stuffer_recv_byte(0, 7); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_and_then_end_of_frame) { -    uint8_t expected[254]; -    int     i; -    for (i = 0; i < 254; i++) { -        expected[i] = i + 1; -    } -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 0xFF); -    for (i = 0; i < 254; i++) { -        byte_stuffer_recv_byte(0, i + 1); -    } -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_non_zero) { -    uint8_t expected[255]; -    int     i; -    for (i = 0; i < 254; i++) { -        expected[i] = i + 1; -    } -    expected[254] = 7; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 0xFF); -    for (i = 0; i < 254; i++) { -        byte_stuffer_recv_byte(0, i + 1); -    } -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 7); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_zero) { -    uint8_t expected[255]; -    int     i; -    for (i = 0; i < 254; i++) { -        expected[i] = i + 1; -    } -    expected[254] = 0; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 0xFF); -    for (i = 0; i < 254; i++) { -        byte_stuffer_recv_byte(0, i + 1); -    } -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_two_long_frames_and_some_more) { -    uint8_t expected[515]; -    int     i; -    int     j; -    for (j = 0; j < 2; j++) { -        for (i = 0; i < 254; i++) { -            expected[i + 254 * j] = i + 1; -        } -    } -    for (i = 0; i < 7; i++) { -        expected[254 * 2 + i] = i + 1; -    } -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 0xFF); -    for (i = 0; i < 254; i++) { -        byte_stuffer_recv_byte(0, i + 1); -    } -    byte_stuffer_recv_byte(0, 0xFF); -    for (i = 0; i < 254; i++) { -        byte_stuffer_recv_byte(0, i + 1); -    } -    byte_stuffer_recv_byte(0, 8); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 3); -    byte_stuffer_recv_byte(0, 4); -    byte_stuffer_recv_byte(0, 5); -    byte_stuffer_recv_byte(0, 6); -    byte_stuffer_recv_byte(0, 7); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_an_all_zeros_frame_that_is_maximum_size) { -    uint8_t expected[MAX_FRAME_SIZE] = {}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    int i; -    byte_stuffer_recv_byte(0, 1); -    for (i = 0; i < MAX_FRAME_SIZE; i++) { -        byte_stuffer_recv_byte(0, 1); -    } -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, doesnt_recv_a_frame_thats_too_long_all_zeroes) { -    uint8_t expected[1] = {0}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).Times(0); -    int i; -    byte_stuffer_recv_byte(0, 1); -    for (i = 0; i < MAX_FRAME_SIZE; i++) { -        byte_stuffer_recv_byte(0, 1); -    } -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, received_frame_is_aborted_when_its_too_long) { -    uint8_t expected[1] = {1}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    int i; -    byte_stuffer_recv_byte(0, 1); -    for (i = 0; i < MAX_FRAME_SIZE; i++) { -        byte_stuffer_recv_byte(0, 1); -    } -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, does_nothing_when_sending_zero_size_frame) { -    EXPECT_EQ(sent_data.size(), 0); -    byte_stuffer_send_frame(0, NULL, 0); -} - -TEST_F(ByteStuffer, send_one_byte_frame) { -    uint8_t data[] = {5}; -    byte_stuffer_send_frame(1, data, 1); -    uint8_t expected[] = {2, 5, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_two_byte_frame) { -    uint8_t data[] = {5, 0x77}; -    byte_stuffer_send_frame(0, data, 2); -    uint8_t expected[] = {3, 5, 0x77, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_one_byte_frame_with_zero) { -    uint8_t data[] = {0}; -    byte_stuffer_send_frame(0, data, 1); -    uint8_t expected[] = {1, 1, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_two_byte_frame_starting_with_zero) { -    uint8_t data[] = {0, 9}; -    byte_stuffer_send_frame(1, data, 2); -    uint8_t expected[] = {1, 2, 9, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_two_byte_frame_starting_with_non_zero) { -    uint8_t data[] = {9, 0}; -    byte_stuffer_send_frame(1, data, 2); -    uint8_t expected[] = {2, 9, 1, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_three_byte_frame_zero_in_the_middle) { -    uint8_t data[] = {9, 0, 0x68}; -    byte_stuffer_send_frame(0, data, 3); -    uint8_t expected[] = {2, 9, 2, 0x68, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_three_byte_frame_data_in_the_middle) { -    uint8_t data[] = {0, 0x55, 0}; -    byte_stuffer_send_frame(0, data, 3); -    uint8_t expected[] = {1, 2, 0x55, 1, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_three_byte_frame_with_all_zeroes) { -    uint8_t data[] = {0, 0, 0}; -    byte_stuffer_send_frame(0, data, 3); -    uint8_t expected[] = {1, 1, 1, 1, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_frame_with_254_non_zeroes) { -    uint8_t data[254]; -    int     i; -    for (i = 0; i < 254; i++) { -        data[i] = i + 1; -    } -    byte_stuffer_send_frame(0, data, 254); -    uint8_t expected[256]; -    expected[0] = 0xFF; -    for (i = 1; i < 255; i++) { -        expected[i] = i; -    } -    expected[255] = 0; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_frame_with_255_non_zeroes) { -    uint8_t data[255]; -    int     i; -    for (i = 0; i < 255; i++) { -        data[i] = i + 1; -    } -    byte_stuffer_send_frame(0, data, 255); -    uint8_t expected[258]; -    expected[0] = 0xFF; -    for (i = 1; i < 255; i++) { -        expected[i] = i; -    } -    expected[255] = 2; -    expected[256] = 255; -    expected[257] = 0; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_frame_with_254_non_zeroes_followed_by_zero) { -    uint8_t data[255]; -    int     i; -    for (i = 0; i < 254; i++) { -        data[i] = i + 1; -    } -    data[254] = 0; -    byte_stuffer_send_frame(0, data, 255); -    uint8_t expected[258]; -    expected[0] = 0xFF; -    for (i = 1; i < 255; i++) { -        expected[i] = i; -    } -    expected[255] = 1; -    expected[256] = 1; -    expected[257] = 0; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_small_packet) { -    uint8_t original_data[] = {1, 2, 3}; -    byte_stuffer_send_frame(0, original_data, sizeof(original_data)); -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(original_data))); -    int i; -    for (auto& d : sent_data) { -        byte_stuffer_recv_byte(1, d); -    } -} - -TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_small_packet_with_zeros) { -    uint8_t original_data[] = {1, 0, 3, 0, 0, 9}; -    byte_stuffer_send_frame(1, original_data, sizeof(original_data)); -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(original_data))); -    int i; -    for (auto& d : sent_data) { -        byte_stuffer_recv_byte(1, d); -    } -} - -TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_254_bytes) { -    uint8_t original_data[254]; -    int     i; -    for (i = 0; i < 254; i++) { -        original_data[i] = i + 1; -    } -    byte_stuffer_send_frame(0, original_data, sizeof(original_data)); -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(original_data))); -    for (auto& d : sent_data) { -        byte_stuffer_recv_byte(1, d); -    } -} - -TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_256_bytes) { -    uint8_t original_data[256]; -    int     i; -    for (i = 0; i < 254; i++) { -        original_data[i] = i + 1; -    } -    original_data[254] = 22; -    original_data[255] = 23; -    byte_stuffer_send_frame(0, original_data, sizeof(original_data)); -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(original_data))); -    for (auto& d : sent_data) { -        byte_stuffer_recv_byte(1, d); -    } -} - -TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_254_bytes_and_then_zero) { -    uint8_t original_data[255]; -    int     i; -    for (i = 0; i < 254; i++) { -        original_data[i] = i + 1; -    } -    original_data[254] = 0; -    byte_stuffer_send_frame(0, original_data, sizeof(original_data)); -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(original_data))); -    for (auto& d : sent_data) { -        byte_stuffer_recv_byte(1, d); -    } -} diff --git a/quantum/serial_link/tests/frame_router_tests.cpp b/quantum/serial_link/tests/frame_router_tests.cpp deleted file mode 100644 index f76dfb33d6..0000000000 --- a/quantum/serial_link/tests/frame_router_tests.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include <array> -extern "C" { -#include "serial_link/protocol/transport.h" -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/frame_router.h" -} - -using testing::_; -using testing::Args; -using testing::ElementsAreArray; - -class FrameRouter : public testing::Test { -   public: -    FrameRouter() : current_router_buffer(nullptr) { -        Instance = this; -        init_byte_stuffer(); -    } - -    ~FrameRouter() { Instance = nullptr; } - -    void send_data(uint8_t link, const uint8_t* data, uint16_t size) { -        auto& buffer = current_router_buffer->send_buffers[link]; -        std::copy(data, data + size, std::back_inserter(buffer)); -    } - -    void receive_data(uint8_t link, uint8_t* data, uint16_t size) { -        int i; -        for (i = 0; i < size; i++) { -            byte_stuffer_recv_byte(link, data[i]); -        } -    } - -    void activate_router(uint8_t num) { -        current_router_buffer = router_buffers + num; -        router_set_master(num == 0); -    } - -    void simulate_transport(uint8_t from, uint8_t to) { -        activate_router(to); -        if (from > to) { -            receive_data(DOWN_LINK, router_buffers[from].send_buffers[UP_LINK].data(), router_buffers[from].send_buffers[UP_LINK].size()); -        } else if (to > from) { -            receive_data(UP_LINK, router_buffers[from].send_buffers[DOWN_LINK].data(), router_buffers[from].send_buffers[DOWN_LINK].size()); -        } -    } - -    MOCK_METHOD3(transport_recv_frame, void(uint8_t from, uint8_t* data, uint16_t size)); - -    std::vector<uint8_t> received_data; - -    struct router_buffer { -        std::vector<uint8_t> send_buffers[2]; -    }; - -    router_buffer  router_buffers[8]; -    router_buffer* current_router_buffer; - -    static FrameRouter* Instance; -}; - -FrameRouter* FrameRouter::Instance = nullptr; - -typedef struct { -    std::array<uint8_t, 4> data; -    uint8_t                extra[16]; -} frame_buffer_t; - -extern "C" { -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { FrameRouter::Instance->send_data(link, data, size); } - -void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { FrameRouter::Instance->transport_recv_frame(from, data, size); } -} - -TEST_F(FrameRouter, master_broadcast_is_received_by_everyone) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(0); -    router_send_frame(0xFF, (uint8_t*)&data, 4); -    EXPECT_GT(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); -    EXPECT_CALL(*this, transport_recv_frame(0, _, _)).With(Args<1, 2>(ElementsAreArray(data.data))); -    simulate_transport(0, 1); -    EXPECT_GT(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[1].send_buffers[UP_LINK].size(), 0); - -    EXPECT_CALL(*this, transport_recv_frame(0, _, _)).With(Args<1, 2>(ElementsAreArray(data.data))); -    simulate_transport(1, 2); -    EXPECT_GT(router_buffers[2].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[2].send_buffers[UP_LINK].size(), 0); -} - -TEST_F(FrameRouter, master_send_is_received_by_targets) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(0); -    router_send_frame((1 << 1) | (1 << 2), (uint8_t*)&data, 4); -    EXPECT_GT(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); - -    simulate_transport(0, 1); -    EXPECT_GT(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[1].send_buffers[UP_LINK].size(), 0); - -    EXPECT_CALL(*this, transport_recv_frame(0, _, _)).With(Args<1, 2>(ElementsAreArray(data.data))); -    simulate_transport(1, 2); -    EXPECT_GT(router_buffers[2].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[2].send_buffers[UP_LINK].size(), 0); - -    EXPECT_CALL(*this, transport_recv_frame(0, _, _)).With(Args<1, 2>(ElementsAreArray(data.data))); -    simulate_transport(2, 3); -    EXPECT_GT(router_buffers[3].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[3].send_buffers[UP_LINK].size(), 0); -} - -TEST_F(FrameRouter, first_link_sends_to_master) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(1); -    router_send_frame(0, (uint8_t*)&data, 4); -    EXPECT_GT(router_buffers[1].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); - -    EXPECT_CALL(*this, transport_recv_frame(1, _, _)).With(Args<1, 2>(ElementsAreArray(data.data))); -    simulate_transport(1, 0); -    EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); -} - -TEST_F(FrameRouter, second_link_sends_to_master) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(2); -    router_send_frame(0, (uint8_t*)&data, 4); -    EXPECT_GT(router_buffers[2].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[2].send_buffers[DOWN_LINK].size(), 0); - -    simulate_transport(2, 1); -    EXPECT_GT(router_buffers[1].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); - -    EXPECT_CALL(*this, transport_recv_frame(2, _, _)).With(Args<1, 2>(ElementsAreArray(data.data))); -    simulate_transport(1, 0); -    EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); -} - -TEST_F(FrameRouter, master_sends_to_master_does_nothing) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(0); -    router_send_frame(0, (uint8_t*)&data, 4); -    EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); -} - -TEST_F(FrameRouter, link_sends_to_other_link_does_nothing) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(1); -    router_send_frame(2, (uint8_t*)&data, 4); -    EXPECT_EQ(router_buffers[1].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); -} - -TEST_F(FrameRouter, master_receives_on_uplink_does_nothing) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(1); -    router_send_frame(0, (uint8_t*)&data, 4); -    EXPECT_GT(router_buffers[1].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); - -    EXPECT_CALL(*this, transport_recv_frame(_, _, _)).Times(0); -    activate_router(0); -    receive_data(UP_LINK, router_buffers[1].send_buffers[UP_LINK].data(), router_buffers[1].send_buffers[UP_LINK].size()); -    EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); -} diff --git a/quantum/serial_link/tests/frame_validator_tests.cpp b/quantum/serial_link/tests/frame_validator_tests.cpp deleted file mode 100644 index 43dc57b633..0000000000 --- a/quantum/serial_link/tests/frame_validator_tests.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "gtest/gtest.h" -#include "gmock/gmock.h" -extern "C" { -#include "serial_link/protocol/frame_validator.h" -} - -using testing::_; -using testing::Args; -using testing::ElementsAreArray; - -class FrameValidator : public testing::Test { -   public: -    FrameValidator() { Instance = this; } - -    ~FrameValidator() { Instance = nullptr; } - -    MOCK_METHOD3(route_incoming_frame, void(uint8_t link, uint8_t* data, uint16_t size)); -    MOCK_METHOD3(byte_stuffer_send_frame, void(uint8_t link, uint8_t* data, uint16_t size)); - -    static FrameValidator* Instance; -}; - -FrameValidator* FrameValidator::Instance = nullptr; - -extern "C" { -void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size) { FrameValidator::Instance->route_incoming_frame(link, data, size); } - -void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { FrameValidator::Instance->byte_stuffer_send_frame(link, data, size); } -} - -TEST_F(FrameValidator, doesnt_validate_frames_under_5_bytes) { -    EXPECT_CALL(*this, route_incoming_frame(_, _, _)).Times(0); -    uint8_t data[] = {1, 2}; -    validator_recv_frame(0, 0, 1); -    validator_recv_frame(0, data, 2); -    validator_recv_frame(0, data, 3); -    validator_recv_frame(0, data, 4); -} - -TEST_F(FrameValidator, validates_one_byte_frame_with_correct_crc) { -    uint8_t data[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; -    EXPECT_CALL(*this, route_incoming_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(data, 1))); -    validator_recv_frame(0, data, 5); -} - -TEST_F(FrameValidator, does_not_validate_one_byte_frame_with_incorrect_crc) { -    uint8_t data[] = {0x44, 0, 0, 0, 0}; -    EXPECT_CALL(*this, route_incoming_frame(_, _, _)).Times(0); -    validator_recv_frame(1, data, 5); -} - -TEST_F(FrameValidator, validates_four_byte_frame_with_correct_crc) { -    uint8_t data[] = {0x44, 0x10, 0xFF, 0x00, 0x74, 0x4E, 0x30, 0xBA}; -    EXPECT_CALL(*this, route_incoming_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(data, 4))); -    validator_recv_frame(1, data, 8); -} - -TEST_F(FrameValidator, validates_five_byte_frame_with_correct_crc) { -    uint8_t data[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; -    EXPECT_CALL(*this, route_incoming_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(data, 5))); -    validator_recv_frame(0, data, 9); -} - -TEST_F(FrameValidator, sends_one_byte_with_correct_crc) { -    uint8_t original[] = {0x44, 0, 0, 0, 0}; -    uint8_t expected[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; -    EXPECT_CALL(*this, byte_stuffer_send_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    validator_send_frame(0, original, 1); -} - -TEST_F(FrameValidator, sends_five_bytes_with_correct_crc) { -    uint8_t original[] = {1, 2, 3, 4, 5, 0, 0, 0, 0}; -    uint8_t expected[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; -    EXPECT_CALL(*this, byte_stuffer_send_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    validator_send_frame(0, original, 5); -} diff --git a/quantum/serial_link/tests/rules.mk b/quantum/serial_link/tests/rules.mk deleted file mode 100644 index b81515bc55..0000000000 --- a/quantum/serial_link/tests/rules.mk +++ /dev/null @@ -1,22 +0,0 @@ -serial_link_byte_stuffer_SRC :=\ -	$(SERIAL_PATH)/tests/byte_stuffer_tests.cpp \ -	$(SERIAL_PATH)/protocol/byte_stuffer.c - -serial_link_frame_validator_SRC := \ -	$(SERIAL_PATH)/tests/frame_validator_tests.cpp \ -	$(SERIAL_PATH)/protocol/frame_validator.c  - -serial_link_frame_router_SRC := \ -	$(SERIAL_PATH)/tests/frame_router_tests.cpp \ -	$(SERIAL_PATH)/protocol/byte_stuffer.c \ -	$(SERIAL_PATH)/protocol/frame_validator.c \ -	$(SERIAL_PATH)/protocol/frame_router.c - -serial_link_triple_buffered_object_SRC := \ -	$(SERIAL_PATH)/tests/triple_buffered_object_tests.cpp \ -	$(SERIAL_PATH)/protocol/triple_buffered_object.c  - -serial_link_transport_SRC := \ -	$(SERIAL_PATH)/tests/transport_tests.cpp \ -	$(SERIAL_PATH)/protocol/transport.c \ -	$(SERIAL_PATH)/protocol/triple_buffered_object.c  diff --git a/quantum/serial_link/tests/testlist.mk b/quantum/serial_link/tests/testlist.mk deleted file mode 100644 index c5edaf478f..0000000000 --- a/quantum/serial_link/tests/testlist.mk +++ /dev/null @@ -1,6 +0,0 @@ -TEST_LIST +=\ -	serial_link_byte_stuffer\ -	serial_link_frame_validator\ -	serial_link_frame_router\ -	serial_link_triple_buffered_object\ -	serial_link_transport diff --git a/quantum/serial_link/tests/transport_tests.cpp b/quantum/serial_link/tests/transport_tests.cpp deleted file mode 100644 index cfd1110460..0000000000 --- a/quantum/serial_link/tests/transport_tests.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "gtest/gtest.h" -#include "gmock/gmock.h" - -using testing::_; -using testing::Args; -using testing::ElementsAreArray; - -extern "C" { -#include "serial_link/protocol/transport.h" -} - -struct test_object1 { -    uint32_t test; -}; - -struct test_object2 { -    uint32_t test1; -    uint32_t test2; -}; - -MASTER_TO_ALL_SLAVES_OBJECT(master_to_slave, test_object1); -MASTER_TO_SINGLE_SLAVE_OBJECT(master_to_single_slave, test_object1); -SLAVE_TO_MASTER_OBJECT(slave_to_master, test_object1); - -static remote_object_t* test_remote_objects[] = { -    REMOTE_OBJECT(master_to_slave), -    REMOTE_OBJECT(master_to_single_slave), -    REMOTE_OBJECT(slave_to_master), -}; - -class Transport : public testing::Test { -   public: -    Transport() { -        Instance = this; -        add_remote_objects(test_remote_objects, sizeof(test_remote_objects) / sizeof(remote_object_t*)); -    } - -    ~Transport() { -        Instance = nullptr; -        reinitialize_serial_link_transport(); -    } - -    MOCK_METHOD0(signal_data_written, void()); -    MOCK_METHOD1(router_send_frame, void(uint8_t destination)); - -    void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { -        router_send_frame(destination); -        std::copy(data, data + size, std::back_inserter(sent_data)); -    } - -    static Transport* Instance; - -    std::vector<uint8_t> sent_data; -}; - -Transport* Transport::Instance = nullptr; - -extern "C" { -void signal_data_written(void) { Transport::Instance->signal_data_written(); } - -void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { Transport::Instance->router_send_frame(destination, data, size); } -} - -TEST_F(Transport, write_to_local_signals_an_event) { -    begin_write_master_to_slave(); -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_slave(); -    begin_write_slave_to_master(); -    EXPECT_CALL(*this, signal_data_written()); -    end_write_slave_to_master(); -    begin_write_master_to_single_slave(1); -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_single_slave(1); -} - -TEST_F(Transport, writes_from_master_to_all_slaves) { -    update_transport(); -    test_object1* obj = begin_write_master_to_slave(); -    obj->test         = 5; -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_slave(); -    EXPECT_CALL(*this, router_send_frame(0xFF)); -    update_transport(); -    transport_recv_frame(0, sent_data.data(), sent_data.size()); -    test_object1* obj2 = read_master_to_slave(); -    EXPECT_NE(obj2, nullptr); -    EXPECT_EQ(obj2->test, 5); -} - -TEST_F(Transport, writes_from_slave_to_master) { -    update_transport(); -    test_object1* obj = begin_write_slave_to_master(); -    obj->test         = 7; -    EXPECT_CALL(*this, signal_data_written()); -    end_write_slave_to_master(); -    EXPECT_CALL(*this, router_send_frame(0)); -    update_transport(); -    transport_recv_frame(3, sent_data.data(), sent_data.size()); -    test_object1* obj2 = read_slave_to_master(2); -    EXPECT_EQ(read_slave_to_master(0), nullptr); -    EXPECT_NE(obj2, nullptr); -    EXPECT_EQ(obj2->test, 7); -} - -TEST_F(Transport, writes_from_master_to_single_slave) { -    update_transport(); -    test_object1* obj = begin_write_master_to_single_slave(3); -    obj->test         = 7; -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_single_slave(3); -    EXPECT_CALL(*this, router_send_frame(4)); -    update_transport(); -    transport_recv_frame(0, sent_data.data(), sent_data.size()); -    test_object1* obj2 = read_master_to_single_slave(); -    EXPECT_NE(obj2, nullptr); -    EXPECT_EQ(obj2->test, 7); -} - -TEST_F(Transport, ignores_object_with_invalid_id) { -    update_transport(); -    test_object1* obj = begin_write_master_to_single_slave(3); -    obj->test         = 7; -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_single_slave(3); -    EXPECT_CALL(*this, router_send_frame(4)); -    update_transport(); -    sent_data[sent_data.size() - 1] = 44; -    transport_recv_frame(0, sent_data.data(), sent_data.size()); -    test_object1* obj2 = read_master_to_single_slave(); -    EXPECT_EQ(obj2, nullptr); -} - -TEST_F(Transport, ignores_object_with_size_too_small) { -    update_transport(); -    test_object1* obj = begin_write_master_to_slave(); -    obj->test         = 7; -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_slave(); -    EXPECT_CALL(*this, router_send_frame(_)); -    update_transport(); -    sent_data[sent_data.size() - 2] = 0; -    transport_recv_frame(0, sent_data.data(), sent_data.size() - 1); -    test_object1* obj2 = read_master_to_slave(); -    EXPECT_EQ(obj2, nullptr); -} - -TEST_F(Transport, ignores_object_with_size_too_big) { -    update_transport(); -    test_object1* obj = begin_write_master_to_slave(); -    obj->test         = 7; -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_slave(); -    EXPECT_CALL(*this, router_send_frame(_)); -    update_transport(); -    sent_data.resize(sent_data.size() + 22); -    sent_data[sent_data.size() - 1] = 0; -    transport_recv_frame(0, sent_data.data(), sent_data.size()); -    test_object1* obj2 = read_master_to_slave(); -    EXPECT_EQ(obj2, nullptr); -} diff --git a/quantum/serial_link/tests/triple_buffered_object_tests.cpp b/quantum/serial_link/tests/triple_buffered_object_tests.cpp deleted file mode 100644 index 8de9bfdebf..0000000000 --- a/quantum/serial_link/tests/triple_buffered_object_tests.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "gtest/gtest.h" -extern "C" { -#include "serial_link/protocol/triple_buffered_object.h" -} - -struct test_object { -    uint8_t  state; -    uint32_t buffer[3]; -}; - -test_object test_object; - -class TripleBufferedObject : public testing::Test { -   public: -    TripleBufferedObject() { triple_buffer_init((triple_buffer_object_t*)&test_object); } -}; - -TEST_F(TripleBufferedObject, writes_and_reads_object) { -    *triple_buffer_begin_write(&test_object) = 0x3456ABCC; -    triple_buffer_end_write(&test_object); -    EXPECT_EQ(*triple_buffer_read(&test_object), 0x3456ABCC); -} - -TEST_F(TripleBufferedObject, does_not_read_empty) { EXPECT_EQ(triple_buffer_read(&test_object), nullptr); } - -TEST_F(TripleBufferedObject, writes_twice_and_reads_object) { -    *triple_buffer_begin_write(&test_object) = 0x3456ABCC; -    triple_buffer_end_write(&test_object); -    *triple_buffer_begin_write(&test_object) = 0x44778899; -    triple_buffer_end_write(&test_object); -    EXPECT_EQ(*triple_buffer_read(&test_object), 0x44778899); -} - -TEST_F(TripleBufferedObject, performs_another_write_in_the_middle_of_read) { -    *triple_buffer_begin_write(&test_object) = 1; -    triple_buffer_end_write(&test_object); -    uint32_t* read                           = triple_buffer_read(&test_object); -    *triple_buffer_begin_write(&test_object) = 2; -    triple_buffer_end_write(&test_object); -    EXPECT_EQ(*read, 1); -    EXPECT_EQ(*triple_buffer_read(&test_object), 2); -    EXPECT_EQ(triple_buffer_read(&test_object), nullptr); -} - -TEST_F(TripleBufferedObject, performs_two_writes_in_the_middle_of_read) { -    *triple_buffer_begin_write(&test_object) = 1; -    triple_buffer_end_write(&test_object); -    uint32_t* read                           = triple_buffer_read(&test_object); -    *triple_buffer_begin_write(&test_object) = 2; -    triple_buffer_end_write(&test_object); -    *triple_buffer_begin_write(&test_object) = 3; -    triple_buffer_end_write(&test_object); -    EXPECT_EQ(*read, 1); -    EXPECT_EQ(*triple_buffer_read(&test_object), 3); -    EXPECT_EQ(triple_buffer_read(&test_object), nullptr); -} diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c index fd676f0729..3ff87710e7 100644 --- a/quantum/split_common/transactions.c +++ b/quantum/split_common/transactions.c @@ -42,8 +42,8 @@      { &dummy, 0, 0, sizeof_member(split_shared_memory_t, member), offsetof(split_shared_memory_t, member), cb }  #define trans_target2initiator_initializer(member) trans_target2initiator_initializer_cb(member, NULL) -#define transport_write(id, data, length)          transport_execute_transaction(id, data, length, NULL, 0) -#define transport_read(id, data, length)           transport_execute_transaction(id, NULL, 0, data, length) +#define transport_write(id, data, length) transport_execute_transaction(id, data, length, NULL, 0) +#define transport_read(id, data, length) transport_execute_transaction(id, NULL, 0, data, length)  #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)  // Forward-declare the RPC callback handlers @@ -157,8 +157,8 @@ static void master_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_ro      memcpy(master_matrix, split_shmem->mmatrix.matrix, sizeof(split_shmem->mmatrix.matrix));  } -#    define TRANSACTIONS_MASTER_MATRIX_MASTER()      TRANSACTION_HANDLER_MASTER(master_matrix) -#    define TRANSACTIONS_MASTER_MATRIX_SLAVE()       TRANSACTION_HANDLER_SLAVE(master_matrix) +#    define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix) +#    define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix)  #    define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS [PUT_MASTER_MATRIX] = trans_initiator2target_initializer(mmatrix.matrix),  #else  // SPLIT_TRANSPORT_MIRROR @@ -235,8 +235,8 @@ static void sync_timer_handlers_slave(matrix_row_t master_matrix[], matrix_row_t      }  } -#    define TRANSACTIONS_SYNC_TIMER_MASTER()      TRANSACTION_HANDLER_MASTER(sync_timer) -#    define TRANSACTIONS_SYNC_TIMER_SLAVE()       TRANSACTION_HANDLER_SLAVE(sync_timer) +#    define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer) +#    define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer)  #    define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS [PUT_SYNC_TIMER] = trans_initiator2target_initializer(sync_timer),  #else  // DISABLE_SYNC_TIMER @@ -300,8 +300,8 @@ static void led_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_t      set_split_host_keyboard_leds(split_shmem->led_state);  } -#    define TRANSACTIONS_LED_STATE_MASTER()      TRANSACTION_HANDLER_MASTER(led_state) -#    define TRANSACTIONS_LED_STATE_SLAVE()       TRANSACTION_HANDLER_SLAVE(led_state) +#    define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state) +#    define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state)  #    define TRANSACTIONS_LED_STATE_REGISTRATIONS [PUT_LED_STATE] = trans_initiator2target_initializer(led_state),  #else  // SPLIT_LED_STATE_ENABLE @@ -357,8 +357,8 @@ static void mods_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave  #    endif  } -#    define TRANSACTIONS_MODS_MASTER()      TRANSACTION_HANDLER_MASTER(mods) -#    define TRANSACTIONS_MODS_SLAVE()       TRANSACTION_HANDLER_SLAVE(mods) +#    define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods) +#    define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods)  #    define TRANSACTIONS_MODS_REGISTRATIONS [PUT_MODS] = trans_initiator2target_initializer(mods),  #else  // SPLIT_MODS_ENABLE @@ -382,8 +382,8 @@ static bool backlight_handlers_master(matrix_row_t master_matrix[], matrix_row_t  static void backlight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { backlight_set(split_shmem->backlight_level); } -#    define TRANSACTIONS_BACKLIGHT_MASTER()      TRANSACTION_HANDLER_MASTER(backlight) -#    define TRANSACTIONS_BACKLIGHT_SLAVE()       TRANSACTION_HANDLER_SLAVE(backlight) +#    define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight) +#    define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight)  #    define TRANSACTIONS_BACKLIGHT_REGISTRATIONS [PUT_BACKLIGHT] = trans_initiator2target_initializer(backlight_level),  #else  // BACKLIGHT_ENABLE @@ -419,8 +419,8 @@ static void rgblight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t s      }  } -#    define TRANSACTIONS_RGBLIGHT_MASTER()      TRANSACTION_HANDLER_MASTER(rgblight) -#    define TRANSACTIONS_RGBLIGHT_SLAVE()       TRANSACTION_HANDLER_SLAVE(rgblight) +#    define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight) +#    define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight)  #    define TRANSACTIONS_RGBLIGHT_REGISTRATIONS [PUT_RGBLIGHT] = trans_initiator2target_initializer(rgblight_sync),  #else  // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) @@ -449,8 +449,8 @@ static void led_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t      led_matrix_set_suspend_state(split_shmem->led_matrix_sync.led_suspend_state);  } -#    define TRANSACTIONS_LED_MATRIX_MASTER()      TRANSACTION_HANDLER_MASTER(led_matrix) -#    define TRANSACTIONS_LED_MATRIX_SLAVE()       TRANSACTION_HANDLER_SLAVE(led_matrix) +#    define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix) +#    define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix)  #    define TRANSACTIONS_LED_MATRIX_REGISTRATIONS [PUT_LED_MATRIX] = trans_initiator2target_initializer(led_matrix_sync),  #else  // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) @@ -479,8 +479,8 @@ static void rgb_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t      rgb_matrix_set_suspend_state(split_shmem->rgb_matrix_sync.rgb_suspend_state);  } -#    define TRANSACTIONS_RGB_MATRIX_MASTER()      TRANSACTION_HANDLER_MASTER(rgb_matrix) -#    define TRANSACTIONS_RGB_MATRIX_SLAVE()       TRANSACTION_HANDLER_SLAVE(rgb_matrix) +#    define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix) +#    define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix)  #    define TRANSACTIONS_RGB_MATRIX_REGISTRATIONS [PUT_RGB_MATRIX] = trans_initiator2target_initializer(rgb_matrix_sync),  #else  // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) @@ -504,8 +504,8 @@ static bool wpm_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave  static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { set_current_wpm(split_shmem->current_wpm); } -#    define TRANSACTIONS_WPM_MASTER()      TRANSACTION_HANDLER_MASTER(wpm) -#    define TRANSACTIONS_WPM_SLAVE()       TRANSACTION_HANDLER_SLAVE(wpm) +#    define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm) +#    define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm)  #    define TRANSACTIONS_WPM_REGISTRATIONS [PUT_WPM] = trans_initiator2target_initializer(current_wpm),  #else  // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) @@ -535,8 +535,8 @@ static void oled_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave      }  } -#    define TRANSACTIONS_OLED_MASTER()      TRANSACTION_HANDLER_MASTER(oled) -#    define TRANSACTIONS_OLED_SLAVE()       TRANSACTION_HANDLER_SLAVE(oled) +#    define TRANSACTIONS_OLED_MASTER() TRANSACTION_HANDLER_MASTER(oled) +#    define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled)  #    define TRANSACTIONS_OLED_REGISTRATIONS [PUT_OLED] = trans_initiator2target_initializer(current_oled_state),  #else  // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) @@ -566,8 +566,8 @@ static void st7565_handlers_slave(matrix_row_t master_matrix[], matrix_row_t sla      }  } -#    define TRANSACTIONS_ST7565_MASTER()      TRANSACTION_HANDLER_MASTER(st7565) -#    define TRANSACTIONS_ST7565_SLAVE()       TRANSACTION_HANDLER_SLAVE(st7565) +#    define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565) +#    define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE(st7565)  #    define TRANSACTIONS_ST7565_REGISTRATIONS [PUT_ST7565] = trans_initiator2target_initializer(current_st7565_state),  #else  // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) diff --git a/quantum/sync_timer.c b/quantum/sync_timer.c new file mode 100644 index 0000000000..de24b463b6 --- /dev/null +++ b/quantum/sync_timer.c @@ -0,0 +1,58 @@ +/* +Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +If you happen to meet one of the copyright holders in a bar you are obligated +to buy them one pint of beer. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "sync_timer.h" +#include "keyboard.h" + +#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) +volatile int32_t sync_timer_ms; + +void sync_timer_init(void) { sync_timer_ms = 0; } + +void sync_timer_update(uint32_t time) { +    if (is_keyboard_master()) return; +    sync_timer_ms = time - timer_read32(); +} + +uint16_t sync_timer_read(void) { +    if (is_keyboard_master()) return timer_read(); +    return sync_timer_read32(); +} + +uint32_t sync_timer_read32(void) { +    if (is_keyboard_master()) return timer_read32(); +    return sync_timer_ms + timer_read32(); +} + +uint16_t sync_timer_elapsed(uint16_t last) { +    if (is_keyboard_master()) return timer_elapsed(last); +    return TIMER_DIFF_16(sync_timer_read(), last); +} + +uint32_t sync_timer_elapsed32(uint32_t last) { +    if (is_keyboard_master()) return timer_elapsed32(last); +    return TIMER_DIFF_32(sync_timer_read32(), last); +} +#endif diff --git a/quantum/sync_timer.h b/quantum/sync_timer.h new file mode 100644 index 0000000000..9ddef45bb2 --- /dev/null +++ b/quantum/sync_timer.h @@ -0,0 +1,54 @@ +/* +Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +If you happen to meet one of the copyright holders in a bar you are obligated +to buy them one pint of beer. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#pragma once + +#include <stdint.h> +#include "timer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) +void     sync_timer_init(void); +void     sync_timer_update(uint32_t time); +uint16_t sync_timer_read(void); +uint32_t sync_timer_read32(void); +uint16_t sync_timer_elapsed(uint16_t last); +uint32_t sync_timer_elapsed32(uint32_t last); +#else +#    define sync_timer_init() +#    define sync_timer_clear() +#    define sync_timer_update(t) +#    define sync_timer_read() timer_read() +#    define sync_timer_read32() timer_read32() +#    define sync_timer_elapsed(t) timer_elapsed(t) +#    define sync_timer_elapsed32(t) timer_elapsed32(t) +#endif + +#ifdef __cplusplus +} +#endif diff --git a/quantum/via_ensure_keycode.h b/quantum/via_ensure_keycode.h index a9c1b8ba5d..1aba0cdd2a 100644 --- a/quantum/via_ensure_keycode.h +++ b/quantum/via_ensure_keycode.h @@ -5,362 +5,338 @@  #ifndef VIA_HAS_BROKEN_KEYCODES -_Static_assert(KC_NO == 0, ""); -_Static_assert(KC_TRNS == 1, ""); +// clang-format off -_Static_assert(KC_A == 0x04, ""); -_Static_assert(KC_B == 0x05, ""); -_Static_assert(KC_C == 0x06, ""); -_Static_assert(KC_D == 0x07, ""); -_Static_assert(KC_E == 0x08, ""); -_Static_assert(KC_F == 0x09, ""); -_Static_assert(KC_G == 0x0A, ""); -_Static_assert(KC_H == 0x0B, ""); -_Static_assert(KC_I == 0x0C, ""); -_Static_assert(KC_J == 0x0D, ""); -_Static_assert(KC_K == 0x0E, ""); -_Static_assert(KC_L == 0x0F, ""); -_Static_assert(KC_M == 0x10, ""); -_Static_assert(KC_N == 0x11, ""); -_Static_assert(KC_O == 0x12, ""); -_Static_assert(KC_P == 0x13, ""); -_Static_assert(KC_Q == 0x14, ""); -_Static_assert(KC_R == 0x15, ""); -_Static_assert(KC_S == 0x16, ""); -_Static_assert(KC_T == 0x17, ""); -_Static_assert(KC_U == 0x18, ""); -_Static_assert(KC_V == 0x19, ""); -_Static_assert(KC_W == 0x1A, ""); -_Static_assert(KC_X == 0x1B, ""); -_Static_assert(KC_Y == 0x1C, ""); -_Static_assert(KC_Z == 0x1D, ""); -_Static_assert(KC_1 == 0x1E, ""); -_Static_assert(KC_2 == 0x1F, ""); -_Static_assert(KC_3 == 0x20, ""); -_Static_assert(KC_4 == 0x21, ""); -_Static_assert(KC_5 == 0x22, ""); -_Static_assert(KC_6 == 0x23, ""); -_Static_assert(KC_7 == 0x24, ""); -_Static_assert(KC_8 == 0x25, ""); -_Static_assert(KC_9 == 0x26, ""); -_Static_assert(KC_0 == 0x27, ""); -_Static_assert(KC_ENTER == 0x28, ""); -_Static_assert(KC_ESCAPE == 0x29, ""); -_Static_assert(KC_BSPACE == 0x2A, ""); -_Static_assert(KC_TAB == 0x2B, ""); -_Static_assert(KC_SPACE == 0x2C, ""); -_Static_assert(KC_MINUS == 0x2D, ""); -_Static_assert(KC_EQUAL == 0x2E, ""); -_Static_assert(KC_LBRACKET == 0x2F, ""); -_Static_assert(KC_RBRACKET == 0x30, ""); -_Static_assert(KC_BSLASH == 0x31, ""); -_Static_assert(KC_SCOLON == 0x33, ""); -_Static_assert(KC_QUOTE == 0x34, ""); -_Static_assert(KC_GRAVE == 0x35, ""); -_Static_assert(KC_COMMA == 0x36, ""); -_Static_assert(KC_DOT == 0x37, ""); -_Static_assert(KC_SLASH == 0x38, ""); -_Static_assert(KC_CAPSLOCK == 0x39, ""); -_Static_assert(KC_F1 == 0x3A, ""); -_Static_assert(KC_F2 == 0x3B, ""); -_Static_assert(KC_F3 == 0x3C, ""); -_Static_assert(KC_F4 == 0x3D, ""); -_Static_assert(KC_F5 == 0x3E, ""); -_Static_assert(KC_F6 == 0x3F, ""); -_Static_assert(KC_F7 == 0x40, ""); -_Static_assert(KC_F8 == 0x41, ""); -_Static_assert(KC_F9 == 0x42, ""); -_Static_assert(KC_F10 == 0x43, ""); -_Static_assert(KC_F11 == 0x44, ""); -_Static_assert(KC_F12 == 0x45, ""); -_Static_assert(KC_PSCREEN == 0x46, ""); -_Static_assert(KC_SCROLLLOCK == 0x47, ""); -_Static_assert(KC_PAUSE == 0x48, ""); -_Static_assert(KC_INSERT == 0x49, ""); -_Static_assert(KC_HOME == 0x4A, ""); -_Static_assert(KC_PGUP == 0x4B, ""); -_Static_assert(KC_DELETE == 0x4C, ""); -_Static_assert(KC_END == 0x4D, ""); -_Static_assert(KC_PGDOWN == 0x4E, ""); -_Static_assert(KC_RIGHT == 0x4F, ""); -_Static_assert(KC_LEFT == 0x50, ""); -_Static_assert(KC_DOWN == 0x51, ""); -_Static_assert(KC_UP == 0x52, ""); -_Static_assert(KC_NUMLOCK == 0x53, ""); -_Static_assert(KC_KP_SLASH == 0x54, ""); -_Static_assert(KC_KP_ASTERISK == 0x55, ""); -_Static_assert(KC_KP_MINUS == 0x56, ""); -_Static_assert(KC_KP_PLUS == 0x57, ""); -_Static_assert(KC_KP_ENTER == 0x58, ""); -_Static_assert(KC_KP_1 == 0x59, ""); -_Static_assert(KC_KP_2 == 0x5A, ""); -_Static_assert(KC_KP_3 == 0x5B, ""); -_Static_assert(KC_KP_4 == 0x5C, ""); -_Static_assert(KC_KP_5 == 0x5D, ""); -_Static_assert(KC_KP_6 == 0x5E, ""); -_Static_assert(KC_KP_7 == 0x5F, ""); -_Static_assert(KC_KP_8 == 0x60, ""); -_Static_assert(KC_KP_9 == 0x61, ""); -_Static_assert(KC_KP_0 == 0x62, ""); -_Static_assert(KC_KP_DOT == 0x63, ""); -_Static_assert(KC_APPLICATION == 0x65, ""); -_Static_assert(KC_KP_EQUAL == 0x67, ""); -_Static_assert(KC_KP_COMMA == 0x85, ""); -_Static_assert(KC_LCTRL == 0xE0, ""); -_Static_assert(KC_LSHIFT == 0xE1, ""); -_Static_assert(KC_LALT == 0xE2, ""); -_Static_assert(KC_LGUI == 0xE3, ""); -_Static_assert(KC_RCTRL == 0xE4, ""); -_Static_assert(KC_RSHIFT == 0xE5, ""); -_Static_assert(KC_RALT == 0xE6, ""); -_Static_assert(KC_RGUI == 0xE7, ""); +_Static_assert(KC_NO                  == 0x0000, ""); +_Static_assert(KC_TRANSPARENT         == 0x0001, ""); -_Static_assert(KC_TILD == 0x235, ""); -_Static_assert(KC_EXLM == 0x21E, ""); -_Static_assert(KC_AT == 0x21F, ""); -_Static_assert(KC_HASH == 0x220, ""); -_Static_assert(KC_DLR == 0x221, ""); -_Static_assert(KC_PERC == 0x222, ""); -_Static_assert(KC_CIRC == 0x223, ""); -_Static_assert(KC_AMPR == 0x224, ""); -_Static_assert(KC_ASTR == 0x225, ""); -_Static_assert(KC_LPRN == 0x226, ""); -_Static_assert(KC_RPRN == 0x227, ""); -_Static_assert(KC_UNDS == 0x22D, ""); -_Static_assert(KC_PLUS == 0x22E, ""); -_Static_assert(KC_LCBR == 0x22F, ""); -_Static_assert(KC_RCBR == 0x230, ""); -_Static_assert(KC_LT == 0x236, ""); -_Static_assert(KC_GT == 0x237, ""); -_Static_assert(KC_COLN == 0x233, ""); -_Static_assert(KC_PIPE == 0x231, ""); -_Static_assert(KC_QUES == 0x238, ""); -_Static_assert(KC_DQUO == 0x234, ""); +_Static_assert(KC_A                   == 0x0004, ""); +_Static_assert(KC_B                   == 0x0005, ""); +_Static_assert(KC_C                   == 0x0006, ""); +_Static_assert(KC_D                   == 0x0007, ""); +_Static_assert(KC_E                   == 0x0008, ""); +_Static_assert(KC_F                   == 0x0009, ""); +_Static_assert(KC_G                   == 0x000A, ""); +_Static_assert(KC_H                   == 0x000B, ""); +_Static_assert(KC_I                   == 0x000C, ""); +_Static_assert(KC_J                   == 0x000D, ""); +_Static_assert(KC_K                   == 0x000E, ""); +_Static_assert(KC_L                   == 0x000F, ""); +_Static_assert(KC_M                   == 0x0010, ""); +_Static_assert(KC_N                   == 0x0011, ""); +_Static_assert(KC_O                   == 0x0012, ""); +_Static_assert(KC_P                   == 0x0013, ""); +_Static_assert(KC_Q                   == 0x0014, ""); +_Static_assert(KC_R                   == 0x0015, ""); +_Static_assert(KC_S                   == 0x0016, ""); +_Static_assert(KC_T                   == 0x0017, ""); +_Static_assert(KC_U                   == 0x0018, ""); +_Static_assert(KC_V                   == 0x0019, ""); +_Static_assert(KC_W                   == 0x001A, ""); +_Static_assert(KC_X                   == 0x001B, ""); +_Static_assert(KC_Y                   == 0x001C, ""); +_Static_assert(KC_Z                   == 0x001D, ""); +_Static_assert(KC_1                   == 0x001E, ""); +_Static_assert(KC_2                   == 0x001F, ""); +_Static_assert(KC_3                   == 0x0020, ""); +_Static_assert(KC_4                   == 0x0021, ""); +_Static_assert(KC_5                   == 0x0022, ""); +_Static_assert(KC_6                   == 0x0023, ""); +_Static_assert(KC_7                   == 0x0024, ""); +_Static_assert(KC_8                   == 0x0025, ""); +_Static_assert(KC_9                   == 0x0026, ""); +_Static_assert(KC_0                   == 0x0027, ""); +_Static_assert(KC_ENTER               == 0x0028, ""); +_Static_assert(KC_ESCAPE              == 0x0029, ""); +_Static_assert(KC_BACKSPACE           == 0x002A, ""); +_Static_assert(KC_TAB                 == 0x002B, ""); +_Static_assert(KC_SPACE               == 0x002C, ""); +_Static_assert(KC_MINUS               == 0x002D, ""); +_Static_assert(KC_EQUAL               == 0x002E, ""); +_Static_assert(KC_LEFT_BRACKET        == 0x002F, ""); +_Static_assert(KC_RIGHT_BRACKET       == 0x0030, ""); +_Static_assert(KC_BACKSLASH           == 0x0031, ""); +_Static_assert(KC_NONUS_HASH          == 0x0032, ""); +_Static_assert(KC_SEMICOLON           == 0x0033, ""); +_Static_assert(KC_QUOTE               == 0x0034, ""); +_Static_assert(KC_GRAVE               == 0x0035, ""); +_Static_assert(KC_COMMA               == 0x0036, ""); +_Static_assert(KC_DOT                 == 0x0037, ""); +_Static_assert(KC_SLASH               == 0x0038, ""); +_Static_assert(KC_CAPS_LOCK           == 0x0039, ""); +_Static_assert(KC_F1                  == 0x003A, ""); +_Static_assert(KC_F2                  == 0x003B, ""); +_Static_assert(KC_F3                  == 0x003C, ""); +_Static_assert(KC_F4                  == 0x003D, ""); +_Static_assert(KC_F5                  == 0x003E, ""); +_Static_assert(KC_F6                  == 0x003F, ""); +_Static_assert(KC_F7                  == 0x0040, ""); +_Static_assert(KC_F8                  == 0x0041, ""); +_Static_assert(KC_F9                  == 0x0042, ""); +_Static_assert(KC_F10                 == 0x0043, ""); +_Static_assert(KC_F11                 == 0x0044, ""); +_Static_assert(KC_F12                 == 0x0045, ""); +_Static_assert(KC_PRINT_SCREEN        == 0x0046, ""); +_Static_assert(KC_SCROLL_LOCK         == 0x0047, ""); +_Static_assert(KC_PAUSE               == 0x0048, ""); +_Static_assert(KC_INSERT              == 0x0049, ""); +_Static_assert(KC_HOME                == 0x004A, ""); +_Static_assert(KC_PAGE_UP             == 0x004B, ""); +_Static_assert(KC_DELETE              == 0x004C, ""); +_Static_assert(KC_END                 == 0x004D, ""); +_Static_assert(KC_PAGE_DOWN           == 0x004E, ""); +_Static_assert(KC_RIGHT               == 0x004F, ""); +_Static_assert(KC_LEFT                == 0x0050, ""); +_Static_assert(KC_DOWN                == 0x0051, ""); +_Static_assert(KC_UP                  == 0x0052, ""); +_Static_assert(KC_NUM_LOCK            == 0x0053, ""); +_Static_assert(KC_KP_SLASH            == 0x0054, ""); +_Static_assert(KC_KP_ASTERISK         == 0x0055, ""); +_Static_assert(KC_KP_MINUS            == 0x0056, ""); +_Static_assert(KC_KP_PLUS             == 0x0057, ""); +_Static_assert(KC_KP_ENTER            == 0x0058, ""); +_Static_assert(KC_KP_1                == 0x0059, ""); +_Static_assert(KC_KP_2                == 0x005A, ""); +_Static_assert(KC_KP_3                == 0x005B, ""); +_Static_assert(KC_KP_4                == 0x005C, ""); +_Static_assert(KC_KP_5                == 0x005D, ""); +_Static_assert(KC_KP_6                == 0x005E, ""); +_Static_assert(KC_KP_7                == 0x005F, ""); +_Static_assert(KC_KP_8                == 0x0060, ""); +_Static_assert(KC_KP_9                == 0x0061, ""); +_Static_assert(KC_KP_0                == 0x0062, ""); +_Static_assert(KC_KP_DOT              == 0x0063, ""); +_Static_assert(KC_NONUS_BACKSLASH     == 0x0064, ""); +_Static_assert(KC_APPLICATION         == 0x0065, ""); +_Static_assert(KC_KB_POWER            == 0x0066, ""); +_Static_assert(KC_KP_EQUAL            == 0x0067, ""); +_Static_assert(KC_F13                 == 0x0068, ""); +_Static_assert(KC_F14                 == 0x0069, ""); +_Static_assert(KC_F15                 == 0x006A, ""); +_Static_assert(KC_F16                 == 0x006B, ""); +_Static_assert(KC_F17                 == 0x006C, ""); +_Static_assert(KC_F18                 == 0x006D, ""); +_Static_assert(KC_F19                 == 0x006E, ""); +_Static_assert(KC_F20                 == 0x006F, ""); +_Static_assert(KC_F21                 == 0x0070, ""); +_Static_assert(KC_F22                 == 0x0071, ""); +_Static_assert(KC_F23                 == 0x0072, ""); +_Static_assert(KC_F24                 == 0x0073, ""); +_Static_assert(KC_EXECUTE             == 0x0074, ""); +_Static_assert(KC_HELP                == 0x0075, ""); +_Static_assert(KC_MENU                == 0x0076, ""); +_Static_assert(KC_SELECT              == 0x0077, ""); +_Static_assert(KC_STOP                == 0x0078, ""); +_Static_assert(KC_AGAIN               == 0x0079, ""); +_Static_assert(KC_UNDO                == 0x007A, ""); +_Static_assert(KC_CUT                 == 0x007B, ""); +_Static_assert(KC_COPY                == 0x007C, ""); +_Static_assert(KC_PASTE               == 0x007D, ""); +_Static_assert(KC_FIND                == 0x007E, ""); -_Static_assert(KC_NONUS_HASH == 0x32, ""); -_Static_assert(KC_NONUS_BSLASH == 0x64, ""); -_Static_assert(KC_RO == 0x87, ""); -_Static_assert(KC_KANA == 0x88, ""); -_Static_assert(KC_JYEN == 0x89, ""); -_Static_assert(KC_HENK == 0x8A, ""); -_Static_assert(KC_MHEN == 0x8B, ""); -_Static_assert(KC_LANG1 == 0x90, ""); -_Static_assert(KC_LANG2 == 0x91, ""); +_Static_assert(KC_LOCKING_CAPS_LOCK   == 0x0082, ""); +_Static_assert(KC_LOCKING_NUM_LOCK    == 0x0083, ""); +_Static_assert(KC_LOCKING_SCROLL_LOCK == 0x0084, ""); +_Static_assert(KC_KP_COMMA            == 0x0085, ""); +_Static_assert(KC_KP_EQUAL_AS400      == 0x0086, ""); +_Static_assert(KC_INTERNATIONAL_1     == 0x0087, ""); +_Static_assert(KC_INTERNATIONAL_2     == 0x0088, ""); +_Static_assert(KC_INTERNATIONAL_3     == 0x0089, ""); +_Static_assert(KC_INTERNATIONAL_4     == 0x008A, ""); +_Static_assert(KC_INTERNATIONAL_5     == 0x008B, ""); +_Static_assert(KC_INTERNATIONAL_6     == 0x008C, ""); +_Static_assert(KC_INTERNATIONAL_7     == 0x008D, ""); +_Static_assert(KC_INTERNATIONAL_8     == 0x008E, ""); +_Static_assert(KC_INTERNATIONAL_9     == 0x008F, ""); +_Static_assert(KC_LANGUAGE_1          == 0x0090, ""); +_Static_assert(KC_LANGUAGE_2          == 0x0091, ""); +_Static_assert(KC_LANGUAGE_3          == 0x0092, ""); +_Static_assert(KC_LANGUAGE_4          == 0x0093, ""); +_Static_assert(KC_LANGUAGE_5          == 0x0094, ""); +_Static_assert(KC_LANGUAGE_6          == 0x0095, ""); +_Static_assert(KC_LANGUAGE_7          == 0x0096, ""); +_Static_assert(KC_LANGUAGE_8          == 0x0097, ""); +_Static_assert(KC_LANGUAGE_9          == 0x0098, ""); +_Static_assert(KC_ALTERNATE_ERASE     == 0x0099, ""); +_Static_assert(KC_SYSTEM_REQUEST      == 0x009A, ""); +_Static_assert(KC_CANCEL              == 0x009B, ""); +_Static_assert(KC_CLEAR               == 0x009C, ""); +_Static_assert(KC_PRIOR               == 0x009D, ""); -_Static_assert(KC_GESC == 0x5C16, ""); -_Static_assert(KC_LSPO == 0x5CD7, ""); -_Static_assert(KC_RSPC == 0x5CD8, ""); -_Static_assert(KC_LCPO == 0x5CF3, ""); -_Static_assert(KC_RCPC == 0x5CF4, ""); -_Static_assert(KC_LAPO == 0x5CF5, ""); -_Static_assert(KC_RAPC == 0x5CF6, ""); -_Static_assert(KC_SFTENT == 0x5CD9, ""); +_Static_assert(KC_OUT                 == 0x00A0, ""); +_Static_assert(KC_OPER                == 0x00A1, ""); +_Static_assert(KC_CLEAR_AGAIN         == 0x00A2, ""); +_Static_assert(KC_CRSEL               == 0x00A3, ""); +_Static_assert(KC_EXSEL               == 0x00A4, ""); -_Static_assert(BL_TOGG == 23743, ""); -_Static_assert(BL_STEP == 23744, ""); -_Static_assert(BL_BRTG == 23745, ""); -_Static_assert(BL_ON == 23739, ""); -_Static_assert(BL_OFF == 23740, ""); -_Static_assert(BL_INC == 23742, ""); -_Static_assert(BL_DEC == 23741, ""); -_Static_assert(RGB_TOG == 23746, ""); -_Static_assert(RGB_MOD == 23747, ""); -_Static_assert(RGB_RMOD == 23748, ""); -_Static_assert(RGB_HUI == 23749, ""); -_Static_assert(RGB_HUD == 23750, ""); -_Static_assert(RGB_SAI == 23751, ""); -_Static_assert(RGB_SAD == 23752, ""); -_Static_assert(RGB_VAI == 23753, ""); -_Static_assert(RGB_VAD == 23754, ""); -_Static_assert(RGB_SPI == 23755, ""); -_Static_assert(RGB_SPD == 23756, ""); -_Static_assert(RGB_M_P == 23757, ""); -_Static_assert(RGB_M_B == 23758, ""); -_Static_assert(RGB_M_R == 23759, ""); -_Static_assert(RGB_M_SW == 23760, ""); -_Static_assert(RGB_M_SN == 23761, ""); -_Static_assert(RGB_M_K == 23762, ""); -_Static_assert(RGB_M_X == 23763, ""); -_Static_assert(RGB_M_G == 23764, ""); -_Static_assert(RGB_M_T == 23765, ""); +_Static_assert(KC_PWR                 == 0x00A5, ""); +_Static_assert(KC_SLEP                == 0x00A6, ""); +_Static_assert(KC_WAKE                == 0x00A7, ""); +_Static_assert(KC_MUTE                == 0x00A8, ""); +_Static_assert(KC_VOLU                == 0x00A9, ""); +_Static_assert(KC_VOLD                == 0x00AA, ""); +_Static_assert(KC_MNXT                == 0x00AB, ""); +_Static_assert(KC_MPRV                == 0x00AC, ""); +_Static_assert(KC_MSTP                == 0x00AD, ""); +_Static_assert(KC_MPLY                == 0x00AE, ""); +_Static_assert(KC_MSEL                == 0x00AF, ""); +_Static_assert(KC_EJCT                == 0x00B0, ""); +_Static_assert(KC_MAIL                == 0x00B1, ""); +_Static_assert(KC_CALC                == 0x00B2, ""); +_Static_assert(KC_MYCM                == 0x00B3, ""); +_Static_assert(KC_WSCH                == 0x00B4, ""); +_Static_assert(KC_WHOM                == 0x00B5, ""); +_Static_assert(KC_WBAK                == 0x00B6, ""); +_Static_assert(KC_WFWD                == 0x00B7, ""); +_Static_assert(KC_WSTP                == 0x00B8, ""); +_Static_assert(KC_WREF                == 0x00B9, ""); +_Static_assert(KC_WFAV                == 0x00BA, ""); +_Static_assert(KC_MFFD                == 0x00BB, ""); +_Static_assert(KC_MRWD                == 0x00BC, ""); +_Static_assert(KC_BRIU                == 0x00BD, ""); +_Static_assert(KC_BRID                == 0x00BE, ""); -_Static_assert(KC_F13 == 104, ""); -_Static_assert(KC_F14 == 105, ""); -_Static_assert(KC_F15 == 106, ""); -_Static_assert(KC_F16 == 107, ""); -_Static_assert(KC_F17 == 108, ""); -_Static_assert(KC_F18 == 109, ""); -_Static_assert(KC_F19 == 110, ""); -_Static_assert(KC_F20 == 111, ""); -_Static_assert(KC_F21 == 112, ""); -_Static_assert(KC_F22 == 113, ""); -_Static_assert(KC_F23 == 114, ""); -_Static_assert(KC_F24 == 115, ""); -_Static_assert(KC_PWR == 165, ""); -_Static_assert(KC_SLEP == 166, ""); -_Static_assert(KC_WAKE == 167, ""); -_Static_assert(KC_EXEC == 116, ""); -_Static_assert(KC_HELP == 117, ""); -_Static_assert(KC_SLCT == 119, ""); -_Static_assert(KC_STOP == 120, ""); -_Static_assert(KC_AGIN == 121, ""); -_Static_assert(KC_UNDO == 122, ""); -_Static_assert(KC_CUT == 123, ""); -_Static_assert(KC_COPY == 124, ""); -_Static_assert(KC_PSTE == 125, ""); -_Static_assert(KC_FIND == 126, ""); -_Static_assert(KC_CALC == 178, ""); -_Static_assert(KC_MAIL == 177, ""); -_Static_assert(KC_MSEL == 175, ""); -_Static_assert(KC_MYCM == 179, ""); -_Static_assert(KC_WSCH == 180, ""); -_Static_assert(KC_WHOM == 181, ""); -_Static_assert(KC_WBAK == 182, ""); -_Static_assert(KC_WFWD == 183, ""); -_Static_assert(KC_WSTP == 184, ""); -_Static_assert(KC_WREF == 185, ""); -_Static_assert(KC_WFAV == 186, ""); -_Static_assert(KC_BRIU == 189, ""); -_Static_assert(KC_BRID == 190, ""); -_Static_assert(KC_MPRV == 172, ""); -_Static_assert(KC_MNXT == 171, ""); -_Static_assert(KC_MUTE == 168, ""); -_Static_assert(KC_VOLD == 170, ""); -_Static_assert(KC_VOLU == 169, ""); -_Static_assert(KC_MSTP == 173, ""); -_Static_assert(KC_MPLY == 174, ""); -_Static_assert(KC_MRWD == 188, ""); -_Static_assert(KC_MFFD == 187, ""); -_Static_assert(KC_EJCT == 176, ""); -_Static_assert(KC_MS_U == 240, ""); -_Static_assert(KC_MS_D == 241, ""); -_Static_assert(KC_MS_L == 242, ""); -_Static_assert(KC_MS_R == 243, ""); -_Static_assert(KC_BTN1 == 244, ""); -_Static_assert(KC_BTN2 == 245, ""); -_Static_assert(KC_BTN3 == 246, ""); -_Static_assert(KC_BTN4 == 247, ""); -_Static_assert(KC_BTN5 == 248, ""); -_Static_assert(KC_WH_U == 249, ""); -_Static_assert(KC_WH_D == 250, ""); -_Static_assert(KC_WH_L == 251, ""); -_Static_assert(KC_WH_R == 252, ""); -_Static_assert(KC_ACL0 == 253, ""); -_Static_assert(KC_ACL1 == 254, ""); -_Static_assert(KC_ACL2 == 255, ""); -_Static_assert(KC_LCAP == 130, ""); -_Static_assert(KC_LNUM == 131, ""); -_Static_assert(KC_LSCR == 132, ""); +_Static_assert(KC_LEFT_CTRL           == 0x00E0, ""); +_Static_assert(KC_LEFT_SHIFT          == 0x00E1, ""); +_Static_assert(KC_LEFT_ALT            == 0x00E2, ""); +_Static_assert(KC_LEFT_GUI            == 0x00E3, ""); +_Static_assert(KC_RIGHT_CTRL          == 0x00E4, ""); +_Static_assert(KC_RIGHT_SHIFT         == 0x00E5, ""); +_Static_assert(KC_RIGHT_ALT           == 0x00E6, ""); +_Static_assert(KC_RIGHT_GUI           == 0x00E7, ""); -_Static_assert(FN_MO13 == 0x5F10, ""); -_Static_assert(FN_MO23 == 0x5F11, ""); +_Static_assert(KC_MS_U                == 0x00F0, ""); +_Static_assert(KC_MS_D                == 0x00F1, ""); +_Static_assert(KC_MS_L                == 0x00F2, ""); +_Static_assert(KC_MS_R                == 0x00F3, ""); +_Static_assert(KC_BTN1                == 0x00F4, ""); +_Static_assert(KC_BTN2                == 0x00F5, ""); +_Static_assert(KC_BTN3                == 0x00F6, ""); +_Static_assert(KC_BTN4                == 0x00F7, ""); +_Static_assert(KC_BTN5                == 0x00F8, ""); +_Static_assert(KC_WH_U                == 0x00F9, ""); +_Static_assert(KC_WH_D                == 0x00FA, ""); +_Static_assert(KC_WH_L                == 0x00FB, ""); +_Static_assert(KC_WH_R                == 0x00FC, ""); +_Static_assert(KC_ACL0                == 0x00FD, ""); +_Static_assert(KC_ACL1                == 0x00FE, ""); +_Static_assert(KC_ACL2                == 0x00FF, ""); -_Static_assert(MACRO00 == 0x5F12, ""); -_Static_assert(MACRO01 == 0x5F13, ""); -_Static_assert(MACRO02 == 0x5F14, ""); -_Static_assert(MACRO03 == 0x5F15, ""); -_Static_assert(MACRO04 == 0x5F16, ""); -_Static_assert(MACRO05 == 0x5F17, ""); -_Static_assert(MACRO06 == 0x5F18, ""); -_Static_assert(MACRO07 == 0x5F19, ""); -_Static_assert(MACRO08 == 0x5F1A, ""); -_Static_assert(MACRO09 == 0x5F1B, ""); -_Static_assert(MACRO10 == 0x5F1C, ""); -_Static_assert(MACRO11 == 0x5F1D, ""); -_Static_assert(MACRO12 == 0x5F1E, ""); -_Static_assert(MACRO13 == 0x5F1F, ""); -_Static_assert(MACRO14 == 0x5F20, ""); -_Static_assert(MACRO15 == 0x5F21, ""); +_Static_assert(KC_EXLM                == 0x021E, ""); +_Static_assert(KC_AT                  == 0x021F, ""); +_Static_assert(KC_HASH                == 0x0220, ""); +_Static_assert(KC_DLR                 == 0x0221, ""); +_Static_assert(KC_PERC                == 0x0222, ""); +_Static_assert(KC_CIRC                == 0x0223, ""); +_Static_assert(KC_AMPR                == 0x0224, ""); +_Static_assert(KC_ASTR                == 0x0225, ""); +_Static_assert(KC_LPRN                == 0x0226, ""); +_Static_assert(KC_RPRN                == 0x0227, ""); +_Static_assert(KC_UNDS                == 0x022D, ""); +_Static_assert(KC_PLUS                == 0x022E, ""); +_Static_assert(KC_LCBR                == 0x022F, ""); +_Static_assert(KC_RCBR                == 0x0230, ""); +_Static_assert(KC_PIPE                == 0x0231, ""); +_Static_assert(KC_COLN                == 0x0233, ""); +_Static_assert(KC_DQUO                == 0x0234, ""); +_Static_assert(KC_TILD                == 0x0235, ""); +_Static_assert(KC_LT                  == 0x0236, ""); +_Static_assert(KC_GT                  == 0x0237, ""); +_Static_assert(KC_QUES                == 0x0238, ""); -_Static_assert(USER00 == 0x5F80, ""); -_Static_assert(USER01 == 0x5F81, ""); -_Static_assert(USER02 == 0x5F82, ""); -_Static_assert(USER03 == 0x5F83, ""); -_Static_assert(USER04 == 0x5F84, ""); -_Static_assert(USER05 == 0x5F85, ""); -_Static_assert(USER06 == 0x5F86, ""); -_Static_assert(USER07 == 0x5F87, ""); -_Static_assert(USER08 == 0x5F88, ""); -_Static_assert(USER09 == 0x5F89, ""); -_Static_assert(USER10 == 0x5F8A, ""); -_Static_assert(USER11 == 0x5F8B, ""); -_Static_assert(USER12 == 0x5F8C, ""); -_Static_assert(USER13 == 0x5F8D, ""); -_Static_assert(USER14 == 0x5F8E, ""); -_Static_assert(USER15 == 0x5F8F, ""); +_Static_assert(RESET                  == 0x5C00, ""); +_Static_assert(DEBUG                  == 0x5C01, ""); -_Static_assert(KC_POWER == 102, ""); -_Static_assert(KC_MENU == 118, ""); -_Static_assert(KC_KP_EQUAL_AS400 == 134, ""); -_Static_assert(KC_INT6 == 140, ""); -_Static_assert(KC_INT7 == 141, ""); -_Static_assert(KC_INT8 == 142, ""); -_Static_assert(KC_INT9 == 143, ""); -_Static_assert(KC_LANG3 == 146, ""); -_Static_assert(KC_LANG4 == 147, ""); -_Static_assert(KC_LANG5 == 148, ""); -_Static_assert(KC_LANG6 == 149, ""); -_Static_assert(KC_LANG7 == 150, ""); -_Static_assert(KC_LANG8 == 151, ""); -_Static_assert(KC_LANG9 == 152, ""); -_Static_assert(KC_ERAS == 153, ""); -_Static_assert(KC_SYSREQ == 154, ""); -_Static_assert(KC_CANCEL == 155, ""); -_Static_assert(KC_CLEAR == 156, ""); -_Static_assert(KC_CLR == 156, ""); -_Static_assert(KC_PRIOR == 157, ""); -_Static_assert(KC_OUT == 160, ""); -_Static_assert(KC_OPER == 161, ""); -_Static_assert(KC_CLEAR_AGAIN == 162, ""); -_Static_assert(KC_CRSEL == 163, ""); -_Static_assert(KC_EXSEL == 164, ""); -_Static_assert(KC_FN0 == 192, ""); -_Static_assert(KC_FN1 == 193, ""); -_Static_assert(KC_FN2 == 194, ""); -_Static_assert(KC_FN3 == 195, ""); -_Static_assert(KC_FN4 == 196, ""); -_Static_assert(KC_FN5 == 197, ""); -_Static_assert(KC_FN6 == 198, ""); -_Static_assert(KC_FN7 == 199, ""); -_Static_assert(KC_FN8 == 200, ""); -_Static_assert(KC_FN9 == 201, ""); -_Static_assert(KC_FN10 == 202, ""); -_Static_assert(KC_FN11 == 203, ""); -_Static_assert(KC_FN12 == 204, ""); -_Static_assert(KC_FN13 == 205, ""); -_Static_assert(KC_FN14 == 206, ""); -_Static_assert(KC_FN15 == 207, ""); -_Static_assert(KC_FN16 == 208, ""); -_Static_assert(KC_FN17 == 209, ""); -_Static_assert(KC_FN18 == 210, ""); -_Static_assert(KC_FN19 == 211, ""); -_Static_assert(KC_FN20 == 212, ""); -_Static_assert(KC_FN21 == 213, ""); -_Static_assert(KC_FN22 == 214, ""); -_Static_assert(KC_FN23 == 215, ""); -_Static_assert(KC_FN24 == 216, ""); -_Static_assert(KC_FN25 == 217, ""); -_Static_assert(KC_FN26 == 218, ""); -_Static_assert(KC_FN27 == 219, ""); -_Static_assert(KC_FN28 == 220, ""); -_Static_assert(KC_FN29 == 221, ""); -_Static_assert(KC_FN30 == 222, ""); -_Static_assert(KC_FN31 == 223, ""); -_Static_assert(RESET == 23552, ""); -_Static_assert(DEBUG == 23553, ""); -_Static_assert(MAGIC_TOGGLE_NKRO == 23572, ""); -_Static_assert(AU_ON == 23581, ""); -_Static_assert(AU_OFF == 23582, ""); -_Static_assert(AU_TOG == 23583, ""); -_Static_assert(CLICKY_TOGGLE == 23584, ""); -_Static_assert(CLICKY_ENABLE == 23585, ""); -_Static_assert(CLICKY_DISABLE == 23586, ""); -_Static_assert(CLICKY_UP == 23587, ""); -_Static_assert(CLICKY_DOWN == 23588, ""); -_Static_assert(CLICKY_RESET == 23589, ""); -_Static_assert(MU_ON == 23590, ""); -_Static_assert(MU_OFF == 23591, ""); -_Static_assert(MU_TOG == 23592, ""); -_Static_assert(MU_MOD == 23593, ""); +_Static_assert(MAGIC_TOGGLE_NKRO      == 0x5C14, ""); + +_Static_assert(KC_GESC                == 0x5C16, ""); + +_Static_assert(AU_ON                  == 0x5C1D, ""); +_Static_assert(AU_OFF                 == 0x5C1E, ""); +_Static_assert(AU_TOG                 == 0x5C1F, ""); + +_Static_assert(CLICKY_TOGGLE          == 0x5C20, ""); +_Static_assert(CLICKY_ENABLE          == 0x5C21, ""); +_Static_assert(CLICKY_DISABLE         == 0x5C22, ""); +_Static_assert(CLICKY_UP              == 0x5C23, ""); +_Static_assert(CLICKY_DOWN            == 0x5C24, ""); +_Static_assert(CLICKY_RESET           == 0x5C25, ""); +_Static_assert(MU_ON                  == 0x5C26, ""); +_Static_assert(MU_OFF                 == 0x5C27, ""); +_Static_assert(MU_TOG                 == 0x5C28, ""); +_Static_assert(MU_MOD                 == 0x5C29, ""); + +_Static_assert(BL_ON                  == 0x5CBB, ""); +_Static_assert(BL_OFF                 == 0x5CBC, ""); +_Static_assert(BL_DEC                 == 0x5CBD, ""); +_Static_assert(BL_INC                 == 0x5CBE, ""); +_Static_assert(BL_TOGG                == 0x5CBF, ""); +_Static_assert(BL_STEP                == 0x5CC0, ""); +_Static_assert(BL_BRTG                == 0x5CC1, ""); +_Static_assert(RGB_TOG                == 0x5CC2, ""); +_Static_assert(RGB_MOD                == 0x5CC3, ""); +_Static_assert(RGB_RMOD               == 0x5CC4, ""); +_Static_assert(RGB_HUI                == 0x5CC5, ""); +_Static_assert(RGB_HUD                == 0x5CC6, ""); +_Static_assert(RGB_SAI                == 0x5CC7, ""); +_Static_assert(RGB_SAD                == 0x5CC8, ""); +_Static_assert(RGB_VAI                == 0x5CC9, ""); +_Static_assert(RGB_VAD                == 0x5CCA, ""); +_Static_assert(RGB_SPI                == 0x5CCB, ""); +_Static_assert(RGB_SPD                == 0x5CCC, ""); +_Static_assert(RGB_M_P                == 0x5CCD, ""); +_Static_assert(RGB_M_B                == 0x5CCE, ""); +_Static_assert(RGB_M_R                == 0x5CCF, ""); +_Static_assert(RGB_M_SW               == 0x5CD0, ""); +_Static_assert(RGB_M_SN               == 0x5CD1, ""); +_Static_assert(RGB_M_K                == 0x5CD2, ""); +_Static_assert(RGB_M_X                == 0x5CD3, ""); +_Static_assert(RGB_M_G                == 0x5CD4, ""); +_Static_assert(RGB_M_T                == 0x5CD5, ""); + +_Static_assert(KC_LSPO                == 0x5CD7, ""); +_Static_assert(KC_RSPC                == 0x5CD8, ""); +_Static_assert(KC_SFTENT              == 0x5CD9, ""); + +_Static_assert(KC_LCPO                == 0x5CF3, ""); +_Static_assert(KC_RCPC                == 0x5CF4, ""); +_Static_assert(KC_LAPO                == 0x5CF5, ""); +_Static_assert(KC_RAPC                == 0x5CF6, ""); + +_Static_assert(FN_MO13                == 0x5F10, ""); +_Static_assert(FN_MO23                == 0x5F11, ""); +_Static_assert(MACRO00                == 0x5F12, ""); +_Static_assert(MACRO01                == 0x5F13, ""); +_Static_assert(MACRO02                == 0x5F14, ""); +_Static_assert(MACRO03                == 0x5F15, ""); +_Static_assert(MACRO04                == 0x5F16, ""); +_Static_assert(MACRO05                == 0x5F17, ""); +_Static_assert(MACRO06                == 0x5F18, ""); +_Static_assert(MACRO07                == 0x5F19, ""); +_Static_assert(MACRO08                == 0x5F1A, ""); +_Static_assert(MACRO09                == 0x5F1B, ""); +_Static_assert(MACRO10                == 0x5F1C, ""); +_Static_assert(MACRO11                == 0x5F1D, ""); +_Static_assert(MACRO12                == 0x5F1E, ""); +_Static_assert(MACRO13                == 0x5F1F, ""); +_Static_assert(MACRO14                == 0x5F20, ""); +_Static_assert(MACRO15                == 0x5F21, ""); + +_Static_assert(USER00                 == 0x5F80, ""); +_Static_assert(USER01                 == 0x5F81, ""); +_Static_assert(USER02                 == 0x5F82, ""); +_Static_assert(USER03                 == 0x5F83, ""); +_Static_assert(USER04                 == 0x5F84, ""); +_Static_assert(USER05                 == 0x5F85, ""); +_Static_assert(USER06                 == 0x5F86, ""); +_Static_assert(USER07                 == 0x5F87, ""); +_Static_assert(USER08                 == 0x5F88, ""); +_Static_assert(USER09                 == 0x5F89, ""); +_Static_assert(USER10                 == 0x5F8A, ""); +_Static_assert(USER11                 == 0x5F8B, ""); +_Static_assert(USER12                 == 0x5F8C, ""); +_Static_assert(USER13                 == 0x5F8D, ""); +_Static_assert(USER14                 == 0x5F8E, ""); +_Static_assert(USER15                 == 0x5F8F, "");  #endif diff --git a/quantum/virtser.h b/quantum/virtser.h new file mode 100644 index 0000000000..df7e87984c --- /dev/null +++ b/quantum/virtser.h @@ -0,0 +1,9 @@ +#pragma once + +void virtser_init(void); + +/* Define this function in your code to process incoming bytes */ +void virtser_recv(const uint8_t ch); + +/* Call this to send a character over the Virtual Serial Device */ +void virtser_send(const uint8_t byte); diff --git a/quantum/visualizer/LICENSE.md b/quantum/visualizer/LICENSE.md deleted file mode 100644 index 22d4c3f08b..0000000000 --- a/quantum/visualizer/LICENSE.md +++ /dev/null @@ -1,29 +0,0 @@ -The files in this project are licensed under the MIT license -It uses the following libraries -uGFX - with it's own license, see the license.html file in the uGFX subfolder for more information -tmk_core - is indirectly used and not included in the repository. It's licensed under the GPLv2 license -Chibios - which is used by tmk_core is licensed under GPLv3. - -Therefore the effective license for any project using the library is GPLv3 - -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/quantum/visualizer/common_gfxconf.h b/quantum/visualizer/common_gfxconf.h deleted file mode 100644 index e0735b37d0..0000000000 --- a/quantum/visualizer/common_gfxconf.h +++ /dev/null @@ -1,354 +0,0 @@ -/** - * This file has a different license to the rest of the uGFX system. - * You can copy, modify and distribute this file as you see fit. - * You do not need to publish your source modifications to this file. - * The only thing you are not permitted to do is to relicense it - * under a different license. - */ - -/** - * Copy this file into your project directory and rename it as gfxconf.h - * Edit your copy to turn on the uGFX features you want to use. - * The values below are the defaults. - * - * Only remove the comments from lines where you want to change the - * default value. This allows definitions to be included from - * driver makefiles when required and provides the best future - * compatibility for your project. - * - * Please use spaces instead of tabs in this file. - */ - -#pragma once - -/////////////////////////////////////////////////////////////////////////// -// GFX - Compatibility options                                           // -/////////////////////////////////////////////////////////////////////////// -//#define GFX_COMPAT_V2                                GFXON -//#define GFX_COMPAT_OLDCOLORS                         GFXON - -/////////////////////////////////////////////////////////////////////////// -// GOS - One of these must be defined, preferably in your Makefile       // -/////////////////////////////////////////////////////////////////////////// -//#define GFX_USE_OS_CHIBIOS                           GFXOFF -//#define GFX_USE_OS_FREERTOS                          GFXOFF -//    #define GFX_FREERTOS_USE_TRACE                   GFXOFF -//#define GFX_USE_OS_WIN32                             GFXOFF -//#define GFX_USE_OS_LINUX                             GFXOFF -//#define GFX_USE_OS_OSX                               GFXOFF -//#define GFX_USE_OS_ECOS                              GFXOFF -//#define GFX_USE_OS_RAWRTOS                           GFXOFF -//#define GFX_USE_OS_ARDUINO                           GFXOFF -//#define GFX_USE_OS_KEIL                              GFXOFF -//#define GFX_USE_OS_RTX5                              GFXOFF -//#define GFX_USE_OS_CMSIS                             GFXOFF -//#define GFX_USE_OS_CMSIS2                            GFXOFF -//#define GFX_USE_OS_RAW32                             GFXOFF -//#define GFX_USE_OS_ZEPHYR                            GFXOFF -//#define GFX_USE_OS_NIOS                              GFXOFF -//#define GFX_USE_OS_QT                                GFXOFF -//    #define INTERRUPTS_OFF()                         optional_code -//    #define INTERRUPTS_ON()                          optional_code - -// Options that (should where relevant) apply to all operating systems -#define GFX_NO_INLINE GFXON -//    #define GFX_COMPILER                             GFX_COMPILER_UNKNOWN -//    #define GFX_SHOW_COMPILER                        GFXOFF -//    #define GFX_CPU                                  GFX_CPU_UNKNOWN -//    #define GFX_CPU_NO_ALIGNMENT_FAULTS              GFXOFF -//    #define GFX_CPU_ENDIAN                           GFX_CPU_ENDIAN_UNKNOWN -//    #define GFX_OS_HEAP_SIZE                         0 -//    #define GFX_OS_NO_INIT                           GFXOFF -//    #define GFX_OS_INIT_NO_WARNING                   GFXOFF -//    #define GFX_OS_PRE_INIT_FUNCTION                 myHardwareInitRoutine -//    #define GFX_OS_EXTRA_INIT_FUNCTION               myOSInitRoutine -//    #define GFX_OS_EXTRA_DEINIT_FUNCTION             myOSDeInitRoutine -//    #define GFX_OS_CALL_UGFXMAIN                     GFXOFF -//    #define GFX_OS_UGFXMAIN_STACKSIZE                0 -//    #define GFX_EMULATE_MALLOC                       GFXOFF -//    #define GFX_MEM_LT64K                            GFXOFF - -/////////////////////////////////////////////////////////////////////////// -// GDISP                                                                 // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GDISP GFXON - -//#define GDISP_NEED_AUTOFLUSH                         GFXOFF -//#define GDISP_NEED_TIMERFLUSH                        GFXOFF -//#define GDISP_NEED_VALIDATION                        GFXON -//#define GDISP_NEED_CLIP                              GFXON -#define GDISP_NEED_CIRCLE GFXON -//#define GDISP_NEED_DUALCIRCLE                        GFXOFF -#define GDISP_NEED_ELLIPSE GFXON -#define GDISP_NEED_ARC GFXON -#define GDISP_NEED_ARCSECTORS GFXON -#define GDISP_NEED_CONVEX_POLYGON GFXON -//#define GDISP_NEED_SCROLL                            GFXOFF -#define GDISP_NEED_PIXELREAD GFXON -#define GDISP_NEED_CONTROL GFXON -//#define GDISP_NEED_QUERY                             GFXOFF -//#define GDISP_NEED_MULTITHREAD                       GFXOFF -//#define GDISP_NEED_STREAMING                         GFXOFF -#define GDISP_NEED_TEXT GFXON -//    #define GDISP_NEED_TEXT_WORDWRAP                 GFXOFF -//    #define GDISP_NEED_TEXT_BOXPADLR                 1 -//    #define GDISP_NEED_TEXT_BOXPADTB                 1 -//    #define GDISP_NEED_ANTIALIAS                     GFXOFF -//    #define GDISP_NEED_UTF8                          GFXOFF -#define GDISP_NEED_TEXT_KERNING GFXON -//    #define GDISP_INCLUDE_FONT_UI1                   GFXOFF -//    #define GDISP_INCLUDE_FONT_UI2                   GFXOFF		// The smallest preferred font. -//    #define GDISP_INCLUDE_FONT_LARGENUMBERS          GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS10          GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS12          GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS16          GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS20          GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS24          GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS32          GFXOFF -#define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12 GFXON -//    #define GDISP_INCLUDE_FONT_FIXED_10X20           GFXOFF -//    #define GDISP_INCLUDE_FONT_FIXED_7X14            GFXOFF -#define GDISP_INCLUDE_FONT_FIXED_5X8 GFXON -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS12_AA       GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS16_AA       GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS20_AA       GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS24_AA       GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA       GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA   GFXOFF -//    #define GDISP_INCLUDE_USER_FONTS                 GFXOFF - -//#define GDISP_NEED_IMAGE                             GFXOFF -//    #define GDISP_NEED_IMAGE_NATIVE                  GFXOFF -//    #define GDISP_NEED_IMAGE_GIF                     GFXOFF -//        #define GDISP_IMAGE_GIF_BLIT_BUFFER_SIZE     32 -//    #define GDISP_NEED_IMAGE_BMP                     GFXOFF -//        #define GDISP_NEED_IMAGE_BMP_1               GFXON -//        #define GDISP_NEED_IMAGE_BMP_4               GFXON -//        #define GDISP_NEED_IMAGE_BMP_4_RLE           GFXON -//        #define GDISP_NEED_IMAGE_BMP_8               GFXON -//        #define GDISP_NEED_IMAGE_BMP_8_RLE           GFXON -//        #define GDISP_NEED_IMAGE_BMP_16              GFXON -//        #define GDISP_NEED_IMAGE_BMP_24              GFXON -//        #define GDISP_NEED_IMAGE_BMP_32              GFXON -//        #define GDISP_IMAGE_BMP_BLIT_BUFFER_SIZE     32 -//    #define GDISP_NEED_IMAGE_JPG                     GFXOFF -//    #define GDISP_NEED_IMAGE_PNG                     GFXOFF -//        #define GDISP_NEED_IMAGE_PNG_INTERLACED      GFXOFF -//        #define GDISP_NEED_IMAGE_PNG_TRANSPARENCY    GFXON -//        #define GDISP_NEED_IMAGE_PNG_BACKGROUND      GFXON -//        #define GDISP_NEED_IMAGE_PNG_ALPHACLIFF      32 -//        #define GDISP_NEED_IMAGE_PNG_PALETTE_124     GFXON -//        #define GDISP_NEED_IMAGE_PNG_PALETTE_8       GFXON -//        #define GDISP_NEED_IMAGE_PNG_GRAYSCALE_124   GFXON -//        #define GDISP_NEED_IMAGE_PNG_GRAYSCALE_8     GFXON -//        #define GDISP_NEED_IMAGE_PNG_GRAYSCALE_16    GFXON -//        #define GDISP_NEED_IMAGE_PNG_GRAYALPHA_8     GFXON -//        #define GDISP_NEED_IMAGE_PNG_GRAYALPHA_16    GFXON -//        #define GDISP_NEED_IMAGE_PNG_RGB_8           GFXON -//        #define GDISP_NEED_IMAGE_PNG_RGB_16          GFXON -//        #define GDISP_NEED_IMAGE_PNG_RGBALPHA_8      GFXON -//        #define GDISP_NEED_IMAGE_PNG_RGBALPHA_16     GFXON -//        #define GDISP_IMAGE_PNG_BLIT_BUFFER_SIZE     32 -//        #define GDISP_IMAGE_PNG_FILE_BUFFER_SIZE     8 -//        #define GDISP_IMAGE_PNG_Z_BUFFER_SIZE        32768 -//    #define GDISP_NEED_IMAGE_ACCOUNTING              GFXOFF - -//#define GDISP_NEED_PIXMAP                            GFXOFF -//    #define GDISP_NEED_PIXMAP_IMAGE                  GFXOFF - -//#define GDISP_DEFAULT_ORIENTATION                    gOrientationLandscape    // If not defined the native hardware orientation is used. -//#define GDISP_LINEBUF_SIZE                           128 -//#define GDISP_STARTUP_COLOR                          GFX_BLACK -#define GDISP_NEED_STARTUP_LOGO GFXOFF - -//#define GDISP_TOTAL_DISPLAYS                         1 - -//#define GDISP_DRIVER_LIST                            GDISPVMT_Win32, GDISPVMT_Win32 -#ifdef GDISP_DRIVER_LIST -//        // For code and speed optimization define as GFXON or GFXOFF if all controllers have the same capability -#    define GDISP_HARDWARE_STREAM_WRITE GFXOFF -#    define GDISP_HARDWARE_STREAM_READ GFXOFF -#    define GDISP_HARDWARE_STREAM_POS GFXOFF -#    define GDISP_HARDWARE_DRAWPIXEL GFXON -#    define GDISP_HARDWARE_CLEARS GFXOFF -#    define GDISP_HARDWARE_FILLS GFXOFF -//#define GDISP_HARDWARE_BITFILLS              GFXOFF -#    define GDISP_HARDWARE_SCROLL GFXOFF -#    define GDISP_HARDWARE_PIXELREAD GFXON -#    define GDISP_HARDWARE_CONTROL GFXON -#    define GDISP_HARDWARE_QUERY GFXOFF -#    define GDISP_HARDWARE_CLIP GFXOFF - -#    define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888 -#endif - -#define GDISP_USE_GFXNET GFXOFF -//    #define GDISP_GFXNET_PORT                        13001 -//    #define GDISP_GFXNET_CUSTOM_LWIP_STARTUP         GFXOFF -//    #define GDISP_DONT_WAIT_FOR_NET_DISPLAY          GFXOFF -//    #define GDISP_GFXNET_UNSAFE_SOCKETS              GFXOFF - -/////////////////////////////////////////////////////////////////////////// -// GWIN                                                                  // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GWIN GFXOFF - -//#define GWIN_NEED_WINDOWMANAGER                      GFXOFF -//    #define GWIN_REDRAW_IMMEDIATE                    GFXOFF -//    #define GWIN_REDRAW_SINGLEOP                     GFXOFF -//    #define GWIN_NEED_FLASHING                       GFXOFF -//        #define GWIN_FLASHING_PERIOD                 250 - -//#define GWIN_NEED_CONSOLE                            GFXOFF -//    #define GWIN_CONSOLE_USE_HISTORY                 GFXOFF -//        #define GWIN_CONSOLE_HISTORY_AVERAGING       GFXOFF -//        #define GWIN_CONSOLE_HISTORY_ATCREATE        GFXOFF -//    #define GWIN_CONSOLE_ESCSEQ                      GFXOFF -//    #define GWIN_CONSOLE_USE_BASESTREAM              GFXOFF -//    #define GWIN_CONSOLE_USE_FLOAT                   GFXOFF -//#define GWIN_NEED_GRAPH                              GFXOFF -//#define GWIN_NEED_GL3D                               GFXOFF - -//#define GWIN_NEED_WIDGET                             GFXOFF -//#define GWIN_FOCUS_HIGHLIGHT_WIDTH                   1 -//    #define GWIN_NEED_LABEL                          GFXOFF -//        #define GWIN_LABEL_ATTRIBUTE                 GFXOFF -//    #define GWIN_NEED_BUTTON                         GFXOFF -//        #define GWIN_BUTTON_LAZY_RELEASE             GFXOFF -//    #define GWIN_NEED_SLIDER                         GFXOFF -//        #define GWIN_SLIDER_NOSNAP                   GFXOFF -//        #define GWIN_SLIDER_DEAD_BAND                5 -//        #define GWIN_SLIDER_TOGGLE_INC               20 -//    #define GWIN_NEED_CHECKBOX                       GFXOFF -//    #define GWIN_NEED_IMAGE                          GFXOFF -//        #define GWIN_NEED_IMAGE_ANIMATION            GFXOFF -//    #define GWIN_NEED_RADIO                          GFXOFF -//    #define GWIN_NEED_LIST                           GFXOFF -//        #define GWIN_NEED_LIST_IMAGES                GFXOFF -//    #define GWIN_NEED_PROGRESSBAR                    GFXOFF -//        #define GWIN_PROGRESSBAR_AUTO                GFXOFF -//    #define GWIN_NEED_KEYBOARD                       GFXOFF -//        #define GWIN_KEYBOARD_DEFAULT_LAYOUT         VirtualKeyboard_English1 -//        #define GWIN_NEED_KEYBOARD_ENGLISH1          GFXON -//    #define GWIN_NEED_TEXTEDIT                       GFXOFF -//    #define GWIN_FLAT_STYLING                        GFXOFF -//    #define GWIN_WIDGET_TAGS                         GFXOFF - -//#define GWIN_NEED_CONTAINERS                         GFXOFF -//    #define GWIN_NEED_CONTAINER                      GFXOFF -//    #define GWIN_NEED_FRAME                          GFXOFF -//    #define GWIN_NEED_TABSET                         GFXOFF -//        #define GWIN_TABSET_TABHEIGHT                18 - -/////////////////////////////////////////////////////////////////////////// -// GTRANS                                                                // -/////////////////////////////////////////////////////////////////////////// -//#define GFX_USE_GTRANS                               GFXOFF - -/////////////////////////////////////////////////////////////////////////// -// GEVENT                                                                // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GEVENT GFXON - -//#define GEVENT_ASSERT_NO_RESOURCE                    GFXOFF -//#define GEVENT_MAXIMUM_SIZE                          32 -//#define GEVENT_MAX_SOURCE_LISTENERS                  32 - -/////////////////////////////////////////////////////////////////////////// -// GTIMER                                                                // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GTIMER GFXOFF - -//#define GTIMER_THREAD_PRIORITY                       gThreadpriorityHigh -//#define GTIMER_THREAD_WORKAREA_SIZE                  2048 - -/////////////////////////////////////////////////////////////////////////// -// GQUEUE                                                                // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GQUEUE GFXOFF - -//#define GQUEUE_NEED_ASYNC                            GFXOFF -//#define GQUEUE_NEED_GSYNC                            GFXOFF -//#define GQUEUE_NEED_FSYNC                            GFXOFF -//#define GQUEUE_NEED_BUFFERS                          GFXOFF - -/////////////////////////////////////////////////////////////////////////// -// GINPUT                                                                // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GINPUT GFXOFF - -//#define GINPUT_NEED_MOUSE                            GFXOFF -//    #define GINPUT_TOUCH_STARTRAW                    GFXOFF -//    #define GINPUT_TOUCH_NOTOUCH                     GFXOFF -//    #define GINPUT_TOUCH_NOCALIBRATE                 GFXOFF -//    #define GINPUT_TOUCH_NOCALIBRATE_GUI             GFXOFF -//    #define GINPUT_MOUSE_POLL_PERIOD                 25 -//    #define GINPUT_MOUSE_CLICK_TIME                  300 -//    #define GINPUT_TOUCH_CXTCLICK_TIME               700 -//    #define GINPUT_TOUCH_USER_CALIBRATION_LOAD       GFXOFF -//    #define GINPUT_TOUCH_USER_CALIBRATION_SAVE       GFXOFF -//    #define GMOUSE_DRIVER_LIST                       GMOUSEVMT_Win32, GMOUSEVMT_Win32 -//    #define GINPUT_TOUCH_CALIBRATION_FONT1           "* Double" -//    #define GINPUT_TOUCH_CALIBRATION_FONT2           "* Narrow" -//    #define GINPUT_TOUCH_CALIBRATION_TITLE           "Calibration" -//    #define GINPUT_TOUCH_CALIBRATION_ERROR           "Calibration Failed!" -//#define GINPUT_NEED_KEYBOARD                         GFXOFF -//    #define GINPUT_KEYBOARD_POLL_PERIOD              200 -//    #define GKEYBOARD_DRIVER_LIST                    GKEYBOARDVMT_Win32, GKEYBOARDVMT_Win32 -//    #define GKEYBOARD_LAYOUT_OFF                     GFXOFF -//        #define GKEYBOARD_LAYOUT_SCANCODE2_US        GFXOFF -//#define GINPUT_NEED_TOGGLE                           GFXOFF -//#define GINPUT_NEED_DIAL                             GFXOFF - -/////////////////////////////////////////////////////////////////////////// -// GFILE                                                                 // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GFILE GFXOFF - -//#define GFILE_NEED_PRINTG                            GFXOFF -//#define GFILE_NEED_SCANG                             GFXOFF -//#define GFILE_NEED_STRINGS                           GFXOFF -//#define GFILE_NEED_FILELISTS                         GFXOFF -//#define GFILE_NEED_STDIO                             GFXOFF -//#define GFILE_NEED_NOAUTOMOUNT                       GFXOFF -//#define GFILE_NEED_NOAUTOSYNC                        GFXOFF - -//#define GFILE_NEED_MEMFS                             GFXOFF -//#define GFILE_NEED_ROMFS                             GFXOFF -//#define GFILE_NEED_RAMFS                             GFXOFF -//#define GFILE_NEED_FATFS                             GFXOFF -//#define GFILE_NEED_NATIVEFS                          GFXOFF -//#define GFILE_NEED_CHBIOSFS                          GFXOFF -//#define GFILE_NEED_USERFS                            GFXOFF - -//#define GFILE_ALLOW_FLOATS                           GFXOFF -//#define GFILE_ALLOW_DEVICESPECIFIC                   GFXOFF -//#define GFILE_MAX_GFILES                             3 - -/////////////////////////////////////////////////////////////////////////// -// GADC                                                                  // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GADC GFXOFF -//    #define GADC_MAX_LOWSPEED_DEVICES                4 - -/////////////////////////////////////////////////////////////////////////// -// GAUDIO                                                                // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GAUDIO GFXOFF -//    #define GAUDIO_NEED_PLAY                         GFXOFF -//    #define GAUDIO_NEED_RECORD                       GFXOFF - -/////////////////////////////////////////////////////////////////////////// -// GMISC                                                                 // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GMISC GFXON - -//#define GMISC_NEED_ARRAYOPS                          GFXOFF -//#define GMISC_NEED_FASTTRIG                          GFXOFF -//#define GMISC_NEED_FIXEDTRIG                         GFXOFF -//#define GMISC_NEED_INVSQRT                           GFXOFF -//    #define GMISC_INVSQRT_MIXED_ENDIAN               GFXOFF -//    #define GMISC_INVSQRT_REAL_SLOW                  GFXOFF -#define GMISC_NEED_MATRIXFLOAT2D GFXON -#define GMISC_NEED_MATRIXFIXED2D GFXOFF -//#define GMISC_NEED_HITTEST_POLY                      GFXOFF diff --git a/quantum/visualizer/default_animations.c b/quantum/visualizer/default_animations.c deleted file mode 100644 index 2f43c67cc8..0000000000 --- a/quantum/visualizer/default_animations.c +++ /dev/null @@ -1,177 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#if defined(VISUALIZER_ENABLE) - -#    include "default_animations.h" -#    include "visualizer.h" -#    ifdef LCD_ENABLE -#        include "lcd_keyframes.h" -#    endif -#    ifdef LCD_BACKLIGHT_ENABLE -#        include "lcd_backlight_keyframes.h" -#    endif - -#    ifdef BACKLIGHT_ENABLE -#        include "led_backlight_keyframes.h" -#    endif - -#    include "visualizer_keyframes.h" - -#    if defined(LCD_ENABLE) || defined(LCD_BACKLIGHT_ENABLE) || defined(BACKLIGHT_ENABLE) - -static bool keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { -#        ifdef LCD_ENABLE -    lcd_keyframe_enable(animation, state); -#        endif -#        ifdef LCD_BACKLIGHT_ENABLE -    lcd_backlight_keyframe_enable(animation, state); -#        endif -#        ifdef BACKLIGHT_ENABLE -    led_backlight_keyframe_enable(animation, state); -#        endif -    return false; -} - -static bool keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { -#        ifdef LCD_ENABLE -    lcd_keyframe_disable(animation, state); -#        endif -#        ifdef LCD_BACKLIGHT_ENABLE -    lcd_backlight_keyframe_disable(animation, state); -#        endif -#        ifdef BACKLIGHT_ENABLE -    led_backlight_keyframe_disable(animation, state); -#        endif -    return false; -} - -static bool keyframe_fade_in(keyframe_animation_t* animation, visualizer_state_t* state) { -    bool ret = false; -#        ifdef LCD_BACKLIGHT_ENABLE -    ret |= lcd_backlight_keyframe_animate_color(animation, state); -#        endif -#        ifdef BACKLIGHT_ENABLE -    ret |= led_backlight_keyframe_fade_in_all(animation, state); -#        endif -    return ret; -} - -static bool keyframe_fade_out(keyframe_animation_t* animation, visualizer_state_t* state) { -    bool ret = false; -#        ifdef LCD_BACKLIGHT_ENABLE -    ret |= lcd_backlight_keyframe_animate_color(animation, state); -#        endif -#        ifdef BACKLIGHT_ENABLE -    ret |= led_backlight_keyframe_fade_out_all(animation, state); -#        endif -    return ret; -} - -// Don't worry, if the startup animation is long, you can use the keyboard like normal -// during that time -keyframe_animation_t default_startup_animation = { -#        if LCD_ENABLE -    .num_frames = 3, -#        else -    .num_frames = 2, -#        endif -    .loop          = false, -    .frame_lengths = {0, -#        if LCD_ENABLE -                      0, -#        endif -                      gfxMillisecondsToTicks(5000)}, -    .frame_functions = -        { -            keyframe_enable, -#        if LCD_ENABLE -            lcd_keyframe_draw_logo, -#        endif -            keyframe_fade_in, -        }, -}; - -keyframe_animation_t default_suspend_animation = { -#        if LCD_ENABLE -    .num_frames = 3, -#        else -    .num_frames = 2, -#        endif -    .loop = false, -    .frame_lengths = -        { -#        if LCD_ENABLE -            0, -#        endif -            gfxMillisecondsToTicks(1000), 0}, -    .frame_functions = -        { -#        if LCD_ENABLE -            lcd_keyframe_display_layer_text, -#        endif -            keyframe_fade_out, -            keyframe_disable, -        }, -}; -#    endif - -#    if defined(BACKLIGHT_ENABLE) -#        define CROSSFADE_TIME 1000 -#        define GRADIENT_TIME 3000 - -keyframe_animation_t led_test_animation = { -    .num_frames = 14, -    .loop       = true, -    .frame_lengths = -        { -            gfxMillisecondsToTicks(1000),            // fade in -            gfxMillisecondsToTicks(1000),            // no op (leds on) -            gfxMillisecondsToTicks(1000),            // fade out -            gfxMillisecondsToTicks(CROSSFADE_TIME),  // crossfade -            gfxMillisecondsToTicks(GRADIENT_TIME),   // left to rigt (outside in) -            gfxMillisecondsToTicks(CROSSFADE_TIME),  // crossfade -            gfxMillisecondsToTicks(GRADIENT_TIME),   // top_to_bottom -            0,                                       // mirror leds -            gfxMillisecondsToTicks(CROSSFADE_TIME),  // crossfade -            gfxMillisecondsToTicks(GRADIENT_TIME),   // left_to_right (mirrored, so inside out) -            gfxMillisecondsToTicks(CROSSFADE_TIME),  // crossfade -            gfxMillisecondsToTicks(GRADIENT_TIME),   // top_to_bottom -            0,                                       // normal leds -            gfxMillisecondsToTicks(CROSSFADE_TIME),  // crossfade - -        }, -    .frame_functions = -        { -            led_backlight_keyframe_fade_in_all, -            keyframe_no_operation, -            led_backlight_keyframe_fade_out_all, -            led_backlight_keyframe_crossfade, -            led_backlight_keyframe_left_to_right_gradient, -            led_backlight_keyframe_crossfade, -            led_backlight_keyframe_top_to_bottom_gradient, -            led_backlight_keyframe_mirror_orientation, -            led_backlight_keyframe_crossfade, -            led_backlight_keyframe_left_to_right_gradient, -            led_backlight_keyframe_crossfade, -            led_backlight_keyframe_top_to_bottom_gradient, -            led_backlight_keyframe_normal_orientation, -            led_backlight_keyframe_crossfade, -        }, -}; -#    endif - -#endif diff --git a/quantum/visualizer/default_animations.h b/quantum/visualizer/default_animations.h deleted file mode 100644 index 9accd89774..0000000000 --- a/quantum/visualizer/default_animations.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#pragma once - -#include "visualizer.h" - -// You can use these default animations, but of course you can also write your own custom ones instead -extern keyframe_animation_t default_startup_animation; -extern keyframe_animation_t default_suspend_animation; - -// An animation for testing and demonstrating the led support, should probably not be used for real world -// cases -extern keyframe_animation_t led_test_animation; diff --git a/quantum/visualizer/lcd_backlight.c b/quantum/visualizer/lcd_backlight.c deleted file mode 100644 index 23978974e3..0000000000 --- a/quantum/visualizer/lcd_backlight.c +++ /dev/null @@ -1,87 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "lcd_backlight.h" -#include <math.h> - -static uint8_t current_hue        = 0; -static uint8_t current_saturation = 0; -static uint8_t current_intensity  = 0; -static uint8_t current_brightness = 0; - -void lcd_backlight_init(void) { -    lcd_backlight_hal_init(); -    lcd_backlight_color(current_hue, current_saturation, current_intensity); -} - -// This code is based on Brian Neltner's blogpost and example code -// "Why every LED light should be using HSI colorspace". -// http://blog.saikoled.com/post/43693602826/why-every-led-light-should-be-using-hsi -static void hsi_to_rgb(float h, float s, float i, uint16_t* r_out, uint16_t* g_out, uint16_t* b_out) { -    unsigned int r, g, b; -    h = fmodf(h, 360.0f);                         // cycle h around to 0-360 degrees -    h = 3.14159f * h / 180.0f;                    // Convert to radians. -    s = s > 0.0f ? (s < 1.0f ? s : 1.0f) : 0.0f;  // clamp s and i to interval [0,1] -    i = i > 0.0f ? (i < 1.0f ? i : 1.0f) : 0.0f; - -    // Math! Thanks in part to Kyle Miller. -    if (h < 2.09439f) { -        r = 65535.0f * i / 3.0f * (1.0f + s * cos(h) / cosf(1.047196667f - h)); -        g = 65535.0f * i / 3.0f * (1.0f + s * (1.0f - cosf(h) / cos(1.047196667f - h))); -        b = 65535.0f * i / 3.0f * (1.0f - s); -    } else if (h < 4.188787) { -        h = h - 2.09439; -        g = 65535.0f * i / 3.0f * (1.0f + s * cosf(h) / cosf(1.047196667f - h)); -        b = 65535.0f * i / 3.0f * (1.0f + s * (1.0f - cosf(h) / cosf(1.047196667f - h))); -        r = 65535.0f * i / 3.0f * (1.0f - s); -    } else { -        h = h - 4.188787; -        b = 65535.0f * i / 3.0f * (1.0f + s * cosf(h) / cosf(1.047196667f - h)); -        r = 65535.0f * i / 3.0f * (1.0f + s * (1.0f - cosf(h) / cosf(1.047196667f - h))); -        g = 65535.0f * i / 3.0f * (1.0f - s); -    } -    *r_out = r > 65535 ? 65535 : r; -    *g_out = g > 65535 ? 65535 : g; -    *b_out = b > 65535 ? 65535 : b; -} - -void lcd_backlight_color(uint8_t hue, uint8_t saturation, uint8_t intensity) { -    uint16_t r, g, b; -    float    hue_f        = 360.0f * (float)hue / 255.0f; -    float    saturation_f = (float)saturation / 255.0f; -    float    intensity_f  = (float)intensity / 255.0f; -    intensity_f *= (float)current_brightness / 255.0f; -    hsi_to_rgb(hue_f, saturation_f, intensity_f, &r, &g, &b); -    current_hue        = hue; -    current_saturation = saturation; -    current_intensity  = intensity; -    lcd_backlight_hal_color(r, g, b); -} - -void lcd_backlight_brightness(uint8_t b) { -    current_brightness = b; -    lcd_backlight_color(current_hue, current_saturation, current_intensity); -} - -uint8_t lcd_get_backlight_brightness(void) { return current_brightness; } diff --git a/quantum/visualizer/lcd_backlight.h b/quantum/visualizer/lcd_backlight.h deleted file mode 100644 index 4ea5b14639..0000000000 --- a/quantum/visualizer/lcd_backlight.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -#include <stdint.h> - -// Helper macros for storing hue, staturation and intensity as unsigned integers -#define LCD_COLOR(hue, saturation, intensity) (hue << 16 | saturation << 8 | intensity) -#define LCD_HUE(color) ((color >> 16) & 0xFF) -#define LCD_SAT(color) ((color >> 8) & 0xFF) -#define LCD_INT(color) (color & 0xFF) - -static inline uint32_t change_lcd_color_intensity(uint32_t color, uint8_t new_intensity) { return (color & 0xFFFFFF00) | new_intensity; } - -void    lcd_backlight_init(void); -void    lcd_backlight_color(uint8_t hue, uint8_t saturation, uint8_t intensity); -void    lcd_backlight_brightness(uint8_t b); -uint8_t lcd_get_backlight_brightness(void); - -void lcd_backlight_hal_init(void); -void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b); diff --git a/quantum/visualizer/lcd_backlight_keyframes.c b/quantum/visualizer/lcd_backlight_keyframes.c deleted file mode 100644 index c13cce311d..0000000000 --- a/quantum/visualizer/lcd_backlight_keyframes.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include "lcd_backlight_keyframes.h" - -bool lcd_backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state) { -    int     frame_length = animation->frame_lengths[animation->current_frame]; -    int     current_pos  = frame_length - animation->time_left_in_frame; -    uint8_t t_h          = LCD_HUE(state->target_lcd_color); -    uint8_t t_s          = LCD_SAT(state->target_lcd_color); -    uint8_t t_i          = LCD_INT(state->target_lcd_color); -    uint8_t p_h          = LCD_HUE(state->prev_lcd_color); -    uint8_t p_s          = LCD_SAT(state->prev_lcd_color); -    uint8_t p_i          = LCD_INT(state->prev_lcd_color); - -    uint8_t d_h1 = t_h - p_h;  // Modulo arithmetic since we want to wrap around -    int     d_h2 = t_h - p_h; -    // Chose the shortest way around -    int d_h = abs(d_h2) < d_h1 ? d_h2 : d_h1; -    int d_s = t_s - p_s; -    int d_i = t_i - p_i; - -    int hue       = (d_h * current_pos) / frame_length; -    int sat       = (d_s * current_pos) / frame_length; -    int intensity = (d_i * current_pos) / frame_length; -    // dprintf("%X -> %X = %X\n", p_h, t_h, hue); -    hue += p_h; -    sat += p_s; -    intensity += p_i; -    state->current_lcd_color = LCD_COLOR(hue, sat, intensity); -    lcd_backlight_color(LCD_HUE(state->current_lcd_color), LCD_SAT(state->current_lcd_color), LCD_INT(state->current_lcd_color)); - -    return true; -} - -bool lcd_backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    state->prev_lcd_color    = state->target_lcd_color; -    state->current_lcd_color = state->target_lcd_color; -    lcd_backlight_color(LCD_HUE(state->current_lcd_color), LCD_SAT(state->current_lcd_color), LCD_INT(state->current_lcd_color)); -    return false; -} - -bool lcd_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    (void)state; -    lcd_backlight_hal_color(0, 0, 0); -    return false; -} - -bool lcd_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    (void)state; -    lcd_backlight_color(LCD_HUE(state->current_lcd_color), LCD_SAT(state->current_lcd_color), LCD_INT(state->current_lcd_color)); -    return false; -} diff --git a/quantum/visualizer/lcd_backlight_keyframes.h b/quantum/visualizer/lcd_backlight_keyframes.h deleted file mode 100644 index 88768dd4a5..0000000000 --- a/quantum/visualizer/lcd_backlight_keyframes.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#pragma once - -#include "visualizer.h" - -// Animates the LCD backlight color between the current color and the target color (of the state) -bool lcd_backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state); -// Sets the backlight color to the target color -bool lcd_backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state); - -bool lcd_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state); -bool lcd_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); diff --git a/quantum/visualizer/lcd_keyframes.c b/quantum/visualizer/lcd_keyframes.c deleted file mode 100644 index 1d6f3dca18..0000000000 --- a/quantum/visualizer/lcd_keyframes.c +++ /dev/null @@ -1,184 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include "lcd_keyframes.h" -#include <string.h> -#include "action_util.h" -#include "led.h" -#include "resources/resources.h" - -bool lcd_keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    gdispClear(White); -    gdispDrawString(0, 10, state->layer_text, state->font_dejavusansbold12, Black); -    return false; -} - -static void format_layer_bitmap_string(uint16_t default_layer, uint16_t layer, char* buffer) { -    for (int i = 0; i < 16; i++) { -        uint32_t mask = (1u << i); -        if (default_layer & mask) { -            if (layer & mask) { -                *buffer = 'B'; -            } else { -                *buffer = 'D'; -            } -        } else if (layer & mask) { -            *buffer = '1'; -        } else { -            *buffer = '0'; -        } -        ++buffer; - -        if (i == 3 || i == 7 || i == 11) { -            *buffer = ' '; -            ++buffer; -        } -    } -    *buffer = 0; -} - -bool lcd_keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    const char* layer_help = "1=On D=Default B=Both"; -    char        layer_buffer[16 + 4];  // 3 spaces and one null terminator -    gdispClear(White); -    gdispDrawString(0, 0, layer_help, state->font_fixed5x8, Black); -    format_layer_bitmap_string(state->status.default_layer, state->status.layer, layer_buffer); -    gdispDrawString(0, 10, layer_buffer, state->font_fixed5x8, Black); -    format_layer_bitmap_string(state->status.default_layer >> 16, state->status.layer >> 16, layer_buffer); -    gdispDrawString(0, 20, layer_buffer, state->font_fixed5x8, Black); -    return false; -} - -static void format_mods_bitmap_string(uint8_t mods, char* buffer) { -    *buffer = ' '; -    ++buffer; - -    for (int i = 0; i < 8; i++) { -        uint32_t mask = (1u << i); -        if (mods & mask) { -            *buffer = '1'; -        } else { -            *buffer = '0'; -        } -        ++buffer; - -        if (i == 3) { -            *buffer = ' '; -            ++buffer; -        } -    } -    *buffer = 0; -} - -bool lcd_keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; - -    const char* title       = "Modifier states"; -    const char* mods_header = " CSAG CSAG "; -    char        status_buffer[12]; - -    gdispClear(White); -    gdispDrawString(0, 0, title, state->font_fixed5x8, Black); -    gdispDrawString(0, 10, mods_header, state->font_fixed5x8, Black); -    format_mods_bitmap_string(state->status.mods, status_buffer); -    gdispDrawString(0, 20, status_buffer, state->font_fixed5x8, Black); - -    return false; -} - -#define LED_STATE_STRING_SIZE sizeof("NUM CAPS SCRL COMP KANA") - -static void get_led_state_string(char* output, visualizer_state_t* state) { -    uint8_t pos = 0; - -    if (state->status.leds & (1u << USB_LED_NUM_LOCK)) { -        memcpy(output + pos, "NUM ", 4); -        pos += 4; -    } -    if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) { -        memcpy(output + pos, "CAPS ", 5); -        pos += 5; -    } -    if (state->status.leds & (1u << USB_LED_SCROLL_LOCK)) { -        memcpy(output + pos, "SCRL ", 5); -        pos += 5; -    } -    if (state->status.leds & (1u << USB_LED_COMPOSE)) { -        memcpy(output + pos, "COMP ", 5); -        pos += 5; -    } -    if (state->status.leds & (1u << USB_LED_KANA)) { -        memcpy(output + pos, "KANA", 4); -        pos += 4; -    } -    output[pos] = 0; -} - -bool lcd_keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    char output[LED_STATE_STRING_SIZE]; -    get_led_state_string(output, state); -    gdispClear(White); -    gdispDrawString(0, 10, output, state->font_dejavusansbold12, Black); -    return false; -} - -bool lcd_keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    gdispClear(White); -    uint8_t y = 10; -    if (state->status.leds) { -        char output[LED_STATE_STRING_SIZE]; -        get_led_state_string(output, state); -        gdispDrawString(0, 1, output, state->font_dejavusansbold12, Black); -        y = 17; -    } -    gdispDrawString(0, y, state->layer_text, state->font_dejavusansbold12, Black); -    return false; -} - -bool lcd_keyframe_draw_logo(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    (void)animation; -    // Read the uGFX documentation for information how to use the displays -    // http://wiki.ugfx.org/index.php/Main_Page -    gdispClear(Black); - -    // You can use static variables for things that can't be found in the animation -    // or state structs, here we use the image - -    // gdispGBlitArea is a tricky function to use since it supports blitting part of the image -    // if you have full screen image, then just use LCD_WIDTH and LCD_HEIGHT for both source and target dimensions -    gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, LCD_WIDTH, (pixel_t*)resource_lcd_logo); - -    return false; -} - -bool lcd_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    (void)state; -    gdispSetPowerMode(powerOff); -    return false; -} - -bool lcd_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    (void)state; -    gdispSetPowerMode(powerOn); -    return false; -} diff --git a/quantum/visualizer/lcd_keyframes.h b/quantum/visualizer/lcd_keyframes.h deleted file mode 100644 index b7125e8323..0000000000 --- a/quantum/visualizer/lcd_keyframes.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#pragma once - -#include "visualizer.h" - -// Displays the layer text centered vertically on the screen -bool lcd_keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays a bitmap (0/1) of all the currently active layers -bool lcd_keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays a bitmap (0/1) of all the currently active mods -bool lcd_keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays the keyboard led states (CAPS (Caps lock), NUM (Num lock), SCRL (Scroll lock), COMP (Compose), KANA) -bool lcd_keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays both the layer text and the led states -bool lcd_keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays the QMK logo on the LCD screen -bool lcd_keyframe_draw_logo(keyframe_animation_t* animation, visualizer_state_t* state); - -bool lcd_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state); -bool lcd_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); diff --git a/quantum/visualizer/led_backlight_keyframes.c b/quantum/visualizer/led_backlight_keyframes.c deleted file mode 100644 index 338ada5227..0000000000 --- a/quantum/visualizer/led_backlight_keyframes.c +++ /dev/null @@ -1,143 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -#include "gfx.h" -#include <math.h> -#include "led_backlight_keyframes.h" - -static uint8_t fade_led_color(keyframe_animation_t* animation, int from, int to) { -    int frame_length = animation->frame_lengths[animation->current_frame]; -    int current_pos  = frame_length - animation->time_left_in_frame; -    int delta        = to - from; -    int luma         = (delta * current_pos) / frame_length; -    luma += from; -    return luma; -} - -static void keyframe_fade_all_leds_from_to(keyframe_animation_t* animation, uint8_t from, uint8_t to) { -    uint8_t luma  = fade_led_color(animation, from, to); -    color_t color = LUMA2COLOR(luma); -    gdispGClear(LED_DISPLAY, color); -} - -// TODO: Should be customizable per keyboard -#define NUM_ROWS LED_HEIGHT -#define NUM_COLS LED_WIDTH - -static uint8_t crossfade_start_frame[NUM_ROWS][NUM_COLS]; -static uint8_t crossfade_end_frame[NUM_ROWS][NUM_COLS]; - -static uint8_t compute_gradient_color(float t, float index, float num) { -    const float two_pi           = M_PI * 2.0f; -    float       normalized_index = (1.0f - index / (num - 1.0f)) * two_pi; -    float       x                = t * two_pi + normalized_index; -    float       v                = 0.5 * (cosf(x) + 1.0f); -    return (uint8_t)(255.0f * v); -} - -bool led_backlight_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    keyframe_fade_all_leds_from_to(animation, 0, 255); -    return true; -} - -bool led_backlight_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    keyframe_fade_all_leds_from_to(animation, 255, 0); -    return true; -} - -bool led_backlight_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    float frame_length = animation->frame_lengths[animation->current_frame]; -    float current_pos  = frame_length - animation->time_left_in_frame; -    float t            = current_pos / frame_length; -    for (int i = 0; i < NUM_COLS; i++) { -        uint8_t color = compute_gradient_color(t, i, NUM_COLS); -        gdispGDrawLine(LED_DISPLAY, i, 0, i, NUM_ROWS - 1, LUMA2COLOR(color)); -    } -    return true; -} - -bool led_backlight_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    float frame_length = animation->frame_lengths[animation->current_frame]; -    float current_pos  = frame_length - animation->time_left_in_frame; -    float t            = current_pos / frame_length; -    for (int i = 0; i < NUM_ROWS; i++) { -        uint8_t color = compute_gradient_color(t, i, NUM_ROWS); -        gdispGDrawLine(LED_DISPLAY, 0, i, NUM_COLS - 1, i, LUMA2COLOR(color)); -    } -    return true; -} - -static void copy_current_led_state(uint8_t* dest) { -    for (int i = 0; i < NUM_ROWS; i++) { -        for (int j = 0; j < NUM_COLS; j++) { -            dest[i * NUM_COLS + j] = gdispGGetPixelColor(LED_DISPLAY, j, i); -        } -    } -} -bool led_backlight_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    if (animation->first_update_of_frame) { -        copy_current_led_state(&crossfade_start_frame[0][0]); -        run_next_keyframe(animation, state); -        copy_current_led_state(&crossfade_end_frame[0][0]); -    } -    for (int i = 0; i < NUM_ROWS; i++) { -        for (int j = 0; j < NUM_COLS; j++) { -            color_t color = LUMA2COLOR(fade_led_color(animation, crossfade_start_frame[i][j], crossfade_end_frame[i][j])); -            gdispGDrawPixel(LED_DISPLAY, j, i, color); -        } -    } -    return true; -} - -bool led_backlight_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    (void)animation; -    gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_180); -    return false; -} - -bool led_backlight_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    (void)animation; -    gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_0); -    return false; -} - -bool led_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    (void)animation; -    gdispGSetPowerMode(LED_DISPLAY, powerOff); -    return false; -} - -bool led_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    (void)animation; -    gdispGSetPowerMode(LED_DISPLAY, powerOn); -    return false; -} diff --git a/quantum/visualizer/led_backlight_keyframes.h b/quantum/visualizer/led_backlight_keyframes.h deleted file mode 100644 index 90153be5eb..0000000000 --- a/quantum/visualizer/led_backlight_keyframes.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -#include "visualizer.h" - -bool led_backlight_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state); - -bool led_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); - -extern keyframe_animation_t led_test_animation; diff --git a/quantum/visualizer/readme.md b/quantum/visualizer/readme.md deleted file mode 100644 index 298efb742f..0000000000 --- a/quantum/visualizer/readme.md +++ /dev/null @@ -1,18 +0,0 @@ -# A visualization library for the TMK keyboard firmware - -This library is designed to work together with the [TMK keyboard firmware](https://github.com/tmk/tmk_keyboard). Currently it only works for [Chibios](http://www.chibios.org/) - flavors, but it would be possible to add support for other configurations as well. The LCD display functionality is provided by the [uGFX library](https://ugfx.io/).  - -## To use this library as a user -You can and should modify the visualizer\_user.c file. Check the comments in the file for more information. - -## To add this library to custom keyboard projects - -1. Add tmk_visualizer as a submodule to your project -1. Set VISUALIZER_DIR in the main keyboard project makefile to point to the submodule -1. Define LCD\_ENABLE and/or LCD\_BACKLIGHT\_ENABLE, to enable support -1. Include the visualizer.mk make file -1. Copy the files in the example\_integration folder to your keyboard project -1. All other files than the callback.c file are included automatically, so you will need to add callback.c to your makefile manually. If you already have a similar file in your project, you can just copy the functions instead of the whole file. -1. Edit the files to match your hardware. You might might want to read the Chibios and UGfx documentation, for more information. -1. If you enable LCD support you might also have to write a custom uGFX display driver, check the uGFX documentation for that. You probably also want to enable SPI support in your Chibios configuration. diff --git a/quantum/visualizer/resources/lcd_logo.c b/quantum/visualizer/resources/lcd_logo.c deleted file mode 100644 index 13bf734cb3..0000000000 --- a/quantum/visualizer/resources/lcd_logo.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include "resources.h" - -// clang-format off - -// To generate an image array like this -// Ensure the image is 128 x 32 or smaller -// Convert the bitmap to a C array using a program like http://www.riuson.com/lcd-image-converter/ -// Ensure the the conversion process produces a monochrome format array - 1 bit/pixel, left to right, top to bottom -// Update array in the source code with the C array produced by the conversion program - -// The image below is generated from lcd_logo.png -__attribute__((weak)) const uint8_t resource_lcd_logo[512] = { -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x02, 0x92, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x92, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x02, 0x92, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0xFE, 0xEE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xEE, 0xF0, 0x01, 0xC6, 0x0D, 0x8C, 0x1F, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0xFE, 0xEE, 0xFE, 0x03, 0xE7, 0x1D, 0x9C, 0x1F, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xEE, 0xF0, 0x06, 0x37, 0x1D, 0xB8, 0x18, 0x0B, 0x59, 0xC8, 0x09, 0xE5, 0x9E, 0x00, -    0x00, 0x1E, 0xEE, 0xF0, 0x06, 0x37, 0xBD, 0xF0, 0x18, 0x6F, 0x7F, 0xEC, 0x9B, 0x37, 0xB3, 0x00, 0x00, 0xFE, 0xEE, 0xFE, 0x06, 0x37, 0xBD, 0xE0, 0x1F, 0x6C, 0x66, 0x6D, 0xD8, 0x36, 0x33, 0x00, -    0x00, 0x1E, 0xEE, 0xF0, 0x06, 0x36, 0xED, 0xF0, 0x1F, 0x6C, 0x66, 0x6D, 0x59, 0xF6, 0x3E, 0x00, 0x00, 0x1F, 0x6D, 0xF0, 0x06, 0x36, 0xED, 0xB8, 0x18, 0x6C, 0x66, 0x67, 0x73, 0x36, 0x30, 0x00, -    0x00, 0xFF, 0x83, 0xFE, 0x03, 0xE6, 0x4D, 0x9C, 0x18, 0x6C, 0x66, 0x67, 0x73, 0x36, 0x1F, 0x00, 0x00, 0x1F, 0xEF, 0xF0, 0x01, 0xC6, 0x0D, 0x8C, 0x18, 0x6C, 0x66, 0x62, 0x21, 0xD6, 0x0E, 0x00, -    0x00, 0xFF, 0xEF, 0xFE, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x02, 0x92, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x92, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x02, 0x92, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; diff --git a/quantum/visualizer/resources/lcd_logo.png b/quantum/visualizer/resources/lcd_logo.png Binary files differdeleted file mode 100644 index 178ef65f15..0000000000 --- a/quantum/visualizer/resources/lcd_logo.png +++ /dev/null diff --git a/quantum/visualizer/resources/resources.h b/quantum/visualizer/resources/resources.h deleted file mode 100644 index 5178fbe55a..0000000000 --- a/quantum/visualizer/resources/resources.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#pragma once - -#include <stdint.h> - -#ifdef LCD_ENABLE -extern const uint8_t resource_lcd_logo[]; -#endif diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c deleted file mode 100644 index 709affbb77..0000000000 --- a/quantum/visualizer/visualizer.c +++ /dev/null @@ -1,483 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "config.h" -#include "visualizer.h" -#include <string.h> -#ifdef PROTOCOL_CHIBIOS -#    include <ch.h> -#endif - -#include "gfx.h" - -#ifdef LCD_BACKLIGHT_ENABLE -#    include "lcd_backlight.h" -#endif - -//#define DEBUG_VISUALIZER - -#ifdef DEBUG_VISUALIZER -#    include "debug.h" -#else -#    include "nodebug.h" -#endif - -#ifdef SERIAL_LINK_ENABLE -#    include "serial_link/protocol/transport.h" -#    include "serial_link/system/serial_link.h" -#endif - -#include "action_util.h" - -// Define this in config.h -#ifndef VISUALIZER_THREAD_PRIORITY -// The visualizer needs gfx thread priorities -#    define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2) -#endif - -static visualizer_keyboard_status_t current_status = {.layer         = 0xFFFFFFFF, -                                                      .default_layer = 0xFFFFFFFF, -                                                      .leds          = 0xFFFFFFFF, -#ifdef BACKLIGHT_ENABLE -                                                      .backlight_level = 0, -#endif -                                                      .mods      = 0xFF, -                                                      .suspended = false, -#ifdef VISUALIZER_USER_DATA_SIZE -                                                      .user_data = {0} -#endif -}; - -static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) { -    return status1->layer == status2->layer && status1->default_layer == status2->default_layer && status1->mods == status2->mods && status1->leds == status2->leds && status1->suspended == status2->suspended -#ifdef BACKLIGHT_ENABLE -           && status1->backlight_level == status2->backlight_level -#endif -#ifdef VISUALIZER_USER_DATA_SIZE -           && memcmp(status1->user_data, status2->user_data, VISUALIZER_USER_DATA_SIZE) == 0 -#endif -        ; -} - -static bool visualizer_enabled = false; - -#ifdef VISUALIZER_USER_DATA_SIZE -static uint8_t user_data[VISUALIZER_USER_DATA_SIZE]; -#endif - -#define MAX_SIMULTANEOUS_ANIMATIONS 4 -static keyframe_animation_t* animations[MAX_SIMULTANEOUS_ANIMATIONS] = {}; - -#ifdef SERIAL_LINK_ENABLE -MASTER_TO_ALL_SLAVES_OBJECT(current_status, visualizer_keyboard_status_t); - -static remote_object_t* remote_objects[] = { -    REMOTE_OBJECT(current_status), -}; - -#endif - -GDisplay* LCD_DISPLAY = 0; -GDisplay* LED_DISPLAY = 0; - -#ifdef LCD_DISPLAY_NUMBER -__attribute__((weak)) GDisplay* get_lcd_display(void) { return gdispGetDisplay(LCD_DISPLAY_NUMBER); } -#endif - -#ifdef LED_DISPLAY_NUMBER -__attribute__((weak)) GDisplay* get_led_display(void) { return gdispGetDisplay(LED_DISPLAY_NUMBER); } -#endif - -void start_keyframe_animation(keyframe_animation_t* animation) { -    animation->current_frame      = -1; -    animation->time_left_in_frame = 0; -    animation->need_update        = true; -    int free_index                = -1; -    for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) { -        if (animations[i] == animation) { -            return; -        } -        if (free_index == -1 && animations[i] == NULL) { -            free_index = i; -        } -    } -    if (free_index != -1) { -        animations[free_index] = animation; -    } -} - -void stop_keyframe_animation(keyframe_animation_t* animation) { -    animation->current_frame         = animation->num_frames; -    animation->time_left_in_frame    = 0; -    animation->need_update           = true; -    animation->first_update_of_frame = false; -    animation->last_update_of_frame  = false; -    for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) { -        if (animations[i] == animation) { -            animations[i] = NULL; -            return; -        } -    } -} - -void stop_all_keyframe_animations(void) { -    for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) { -        if (animations[i]) { -            animations[i]->current_frame         = animations[i]->num_frames; -            animations[i]->time_left_in_frame    = 0; -            animations[i]->need_update           = true; -            animations[i]->first_update_of_frame = false; -            animations[i]->last_update_of_frame  = false; -            animations[i]                        = NULL; -        } -    } -} - -static uint8_t get_num_running_animations(void) { -    uint8_t count = 0; -    for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) { -        count += animations[i] ? 1 : 0; -    } -    return count; -} - -static bool update_keyframe_animation(keyframe_animation_t* animation, visualizer_state_t* state, systemticks_t delta, systemticks_t* sleep_time) { -    // TODO: Clean up this messy code -    dprintf("Animation frame%d, left %d, delta %d\n", animation->current_frame, animation->time_left_in_frame, delta); -    if (animation->current_frame == animation->num_frames) { -        animation->need_update = false; -        return false; -    } -    if (animation->current_frame == -1) { -        animation->current_frame         = 0; -        animation->time_left_in_frame    = animation->frame_lengths[0]; -        animation->need_update           = true; -        animation->first_update_of_frame = true; -    } else { -        animation->time_left_in_frame -= delta; -        while (animation->time_left_in_frame <= 0) { -            int left = animation->time_left_in_frame; -            if (animation->need_update) { -                animation->time_left_in_frame   = 0; -                animation->last_update_of_frame = true; -                (*animation->frame_functions[animation->current_frame])(animation, state); -                animation->last_update_of_frame = false; -            } -            animation->current_frame++; -            animation->need_update           = true; -            animation->first_update_of_frame = true; -            if (animation->current_frame == animation->num_frames) { -                if (animation->loop) { -                    animation->current_frame = 0; -                } else { -                    stop_keyframe_animation(animation); -                    return false; -                } -            } -            delta                         = -left; -            animation->time_left_in_frame = animation->frame_lengths[animation->current_frame]; -            animation->time_left_in_frame -= delta; -        } -    } -    if (animation->need_update) { -        animation->need_update           = (*animation->frame_functions[animation->current_frame])(animation, state); -        animation->first_update_of_frame = false; -    } - -    systemticks_t wanted_sleep = animation->need_update ? gfxMillisecondsToTicks(10) : (unsigned)animation->time_left_in_frame; -    if (wanted_sleep < *sleep_time) { -        *sleep_time = wanted_sleep; -    } - -    return true; -} - -void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* state) { -    int next_frame = animation->current_frame + 1; -    if (next_frame == animation->num_frames) { -        next_frame = 0; -    } -    keyframe_animation_t temp_animation  = *animation; -    temp_animation.current_frame         = next_frame; -    temp_animation.time_left_in_frame    = animation->frame_lengths[next_frame]; -    temp_animation.first_update_of_frame = true; -    temp_animation.last_update_of_frame  = false; -    temp_animation.need_update           = false; -    visualizer_state_t temp_state        = *state; -    (*temp_animation.frame_functions[next_frame])(&temp_animation, &temp_state); -} - -// TODO: Optimize the stack size, this is probably way too big -static DECLARE_THREAD_STACK(visualizerThreadStack, 1024); -static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { -    (void)arg; - -    GListener event_listener; -    geventListenerInit(&event_listener); -    geventAttachSource(&event_listener, (GSourceHandle)¤t_status, 0); - -    visualizer_keyboard_status_t initial_status = { -        .default_layer = 0xFFFFFFFF, -        .layer         = 0xFFFFFFFF, -        .mods          = 0xFF, -        .leds          = 0xFFFFFFFF, -        .suspended     = false, -#ifdef BACKLIGHT_ENABLE -        .backlight_level = 0, -#endif -#ifdef VISUALIZER_USER_DATA_SIZE -        .user_data = {0}, -#endif -    }; - -    visualizer_state_t state = {.status            = initial_status, -                                .current_lcd_color = 0, -#ifdef LCD_ENABLE -                                .font_fixed5x8         = gdispOpenFont("fixed_5x8"), -                                .font_dejavusansbold12 = gdispOpenFont("DejaVuSansBold12") -#endif -    }; -    initialize_user_visualizer(&state); -    state.prev_lcd_color = state.current_lcd_color; - -#ifdef LCD_BACKLIGHT_ENABLE -    lcd_backlight_color(LCD_HUE(state.current_lcd_color), LCD_SAT(state.current_lcd_color), LCD_INT(state.current_lcd_color)); -#endif - -    systemticks_t sleep_time   = TIME_INFINITE; -    systemticks_t current_time = gfxSystemTicks(); -    bool          force_update = true; - -    while (true) { -        systemticks_t new_time = gfxSystemTicks(); -        systemticks_t delta    = new_time - current_time; -        current_time           = new_time; -        bool enabled           = visualizer_enabled; -        if (force_update || !same_status(&state.status, ¤t_status)) { -            force_update = false; -#if BACKLIGHT_ENABLE -            if (current_status.backlight_level != state.status.backlight_level) { -                if (current_status.backlight_level != 0) { -                    gdispGSetPowerMode(LED_DISPLAY, powerOn); -                    uint16_t percent = (uint16_t)current_status.backlight_level * 100 / BACKLIGHT_LEVELS; -                    gdispGSetBacklight(LED_DISPLAY, percent); -                } else { -                    gdispGSetPowerMode(LED_DISPLAY, powerOff); -                } -                state.status.backlight_level = current_status.backlight_level; -            } -#endif -            if (visualizer_enabled) { -                if (current_status.suspended) { -                    stop_all_keyframe_animations(); -                    visualizer_enabled = false; -                    state.status       = current_status; -                    user_visualizer_suspend(&state); -                } else { -                    visualizer_keyboard_status_t prev_status = state.status; -                    state.status                             = current_status; -                    update_user_visualizer_state(&state, &prev_status); -                } -                state.prev_lcd_color = state.current_lcd_color; -            } -        } -        if (!enabled && state.status.suspended && current_status.suspended == false) { -            // Setting the status to the initial status will force an update -            // when the visualizer is enabled again -            state.status           = initial_status; -            state.status.suspended = false; -            stop_all_keyframe_animations(); -            user_visualizer_resume(&state); -            state.prev_lcd_color = state.current_lcd_color; -        } -        sleep_time = TIME_INFINITE; -        for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) { -            if (animations[i]) { -                update_keyframe_animation(animations[i], &state, delta, &sleep_time); -            } -        } -#ifdef BACKLIGHT_ENABLE -        gdispGFlush(LED_DISPLAY); -#endif - -#ifdef LCD_ENABLE -        gdispGFlush(LCD_DISPLAY); -#endif - -#ifdef EMULATOR -        draw_emulator(); -#endif -        // Enable the visualizer when the startup or the suspend animation has finished -        if (!visualizer_enabled && state.status.suspended == false && get_num_running_animations() == 0) { -            visualizer_enabled = true; -            force_update       = true; -            sleep_time         = 0; -        } - -        systemticks_t after_update = gfxSystemTicks(); -        unsigned      update_delta = after_update - current_time; -        if (sleep_time != TIME_INFINITE) { -            if (sleep_time > update_delta) { -                sleep_time -= update_delta; -            } else { -                sleep_time = 0; -            } -        } -        dprintf("Update took %d, last delta %d, sleep_time %d\n", update_delta, delta, sleep_time); -#ifdef PROTOCOL_CHIBIOS -        // The gEventWait function really takes milliseconds, even if the documentation says ticks. -        // Unfortunately there's no generic ugfx conversion from system time to milliseconds, -        // so let's do it in a platform dependent way. - -        // On windows the system ticks is the same as milliseconds anyway -        if (sleep_time != TIME_INFINITE) { -            sleep_time = TIME_I2MS(sleep_time); -        } -#endif -        geventEventWait(&event_listener, sleep_time); -    } -#ifdef LCD_ENABLE -    gdispCloseFont(state.font_fixed5x8); -    gdispCloseFont(state.font_dejavusansbold12); -#endif - -    return 0; -} - -void visualizer_init(void) { -    gfxInit(); - -#ifdef LCD_BACKLIGHT_ENABLE -    lcd_backlight_init(); -#endif - -#ifdef SERIAL_LINK_ENABLE -    add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*)); -#endif - -#ifdef LCD_ENABLE -    LCD_DISPLAY = get_lcd_display(); -#endif - -#ifdef BACKLIGHT_ENABLE -    LED_DISPLAY = get_led_display(); -#endif - -    // We are using a low priority thread, the idea is to have it run only -    // when the main thread is sleeping during the matrix scanning -    gfxThreadCreate(visualizerThreadStack, sizeof(visualizerThreadStack), VISUALIZER_THREAD_PRIORITY, visualizerThread, NULL); -} - -void update_status(bool changed) { -    if (changed) { -        GSourceListener* listener = geventGetSourceListener((GSourceHandle)¤t_status, NULL); -        if (listener) { -            geventSendEvent(listener); -        } -    } -#ifdef SERIAL_LINK_ENABLE -    static systime_t last_update    = 0; -    systime_t        current_update = chVTGetSystemTimeX(); -    systime_t        delta          = current_update - last_update; -    if (changed || delta > TIME_MS2I(10)) { -        last_update                     = current_update; -        visualizer_keyboard_status_t* r = begin_write_current_status(); -        *r                              = current_status; -        end_write_current_status(); -    } -#endif -} - -uint8_t visualizer_get_mods() { -    uint8_t mods = get_mods(); - -#ifndef NO_ACTION_ONESHOT -    if (!has_oneshot_mods_timed_out()) { -        mods |= get_oneshot_mods(); -    } -#endif -    return mods; -} - -#ifdef VISUALIZER_USER_DATA_SIZE -void visualizer_set_user_data(void* u) { memcpy(user_data, u, VISUALIZER_USER_DATA_SIZE); } -#endif - -void visualizer_update(layer_state_t default_state, layer_state_t state, uint8_t mods, uint32_t leds) { -    // Note that there's a small race condition here, the thread could read -    // a state where one of these are set but not the other. But this should -    // not really matter as it will be fixed during the next loop step. -    // Alternatively a mutex could be used instead of the volatile variables - -    bool changed = false; -#ifdef SERIAL_LINK_ENABLE -    if (is_serial_link_connected()) { -        visualizer_keyboard_status_t* new_status = read_current_status(); -        if (new_status) { -            if (!same_status(¤t_status, new_status)) { -                changed        = true; -                current_status = *new_status; -            } -        } -    } else { -#else -    { -#endif -        visualizer_keyboard_status_t new_status = { -            .layer         = state, -            .default_layer = default_state, -            .mods          = mods, -            .leds          = leds, -#ifdef BACKLIGHT_ENABLE -            .backlight_level = current_status.backlight_level, -#endif -            .suspended = current_status.suspended, -        }; -#ifdef VISUALIZER_USER_DATA_SIZE -        memcpy(new_status.user_data, user_data, VISUALIZER_USER_DATA_SIZE); -#endif -        if (!same_status(¤t_status, &new_status)) { -            changed        = true; -            current_status = new_status; -        } -    } -    update_status(changed); -} - -void visualizer_suspend(void) { -    current_status.suspended = true; -    update_status(true); -} - -void visualizer_resume(void) { -    current_status.suspended = false; -    update_status(true); -} - -#ifdef BACKLIGHT_ENABLE -void backlight_set(uint8_t level) { -    current_status.backlight_level = level; -    update_status(true); -} -#endif diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h deleted file mode 100644 index 627c80a305..0000000000 --- a/quantum/visualizer/visualizer.h +++ /dev/null @@ -1,154 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -#include <stdlib.h> -#include <stdint.h> -#include <stdbool.h> - -#include "config.h" -#include "gfx.h" -#include "action_layer.h" - -#ifdef LCD_BACKLIGHT_ENABLE -#    include "lcd_backlight.h" -#endif - -#ifdef BACKLIGHT_ENABLE -#    include "backlight.h" -#endif - -// use this function to merge both real_mods and oneshot_mods in a uint16_t -uint8_t visualizer_get_mods(void); - -// This need to be called once at the start -void visualizer_init(void); -// This should be called at every matrix scan -void visualizer_update(layer_state_t default_state, layer_state_t state, uint8_t mods, uint32_t leds); - -// This should be called when the keyboard goes to suspend state -void visualizer_suspend(void); -// This should be called when the keyboard wakes up from suspend state -void visualizer_resume(void); - -// These functions are week, so they can be overridden by the keyboard -// if needed -GDisplay* get_lcd_display(void); -GDisplay* get_led_display(void); - -// For emulator builds, this function need to be implemented -#ifdef EMULATOR -void draw_emulator(void); -#endif - -// If you need support for more than 16 keyframes per animation, you can change this -#define MAX_VISUALIZER_KEY_FRAMES 16 - -struct keyframe_animation_t; - -typedef struct { -    layer_state_t layer; -    layer_state_t default_layer; -    uint32_t      leds;  // See led.h for available statuses -    uint8_t       mods; -    bool          suspended; -#ifdef BACKLIGHT_ENABLE -    uint8_t backlight_level; -#endif -#ifdef VISUALIZER_USER_DATA_SIZE -    uint8_t user_data[VISUALIZER_USER_DATA_SIZE]; -#endif -} visualizer_keyboard_status_t; - -// The state struct is used by the various keyframe functions -// It's also used for setting the LCD color and layer text -// from the user customized code -typedef struct visualizer_state_t { -    // The user code should primarily be modifying these -    uint32_t    target_lcd_color; -    const char* layer_text; - -    // The user visualizer(and animation functions) can read these -    visualizer_keyboard_status_t status; - -    // These are used by the animation functions -    uint32_t current_lcd_color; -    uint32_t prev_lcd_color; -#ifdef LCD_ENABLE -    gFont font_fixed5x8; -    gFont font_dejavusansbold12; -#endif -} visualizer_state_t; - -// Any custom keyframe function should have this signature -// return true to get continuous updates, otherwise you will only get one -// update per frame -typedef bool (*frame_func)(struct keyframe_animation_t*, visualizer_state_t*); - -// Represents a keyframe animation, so fields are internal to the system -// while others are meant to be initialized by the user code -typedef struct keyframe_animation_t { -    // These should be initialized -    int        num_frames; -    bool       loop; -    int        frame_lengths[MAX_VISUALIZER_KEY_FRAMES]; -    frame_func frame_functions[MAX_VISUALIZER_KEY_FRAMES]; - -    // Used internally by the system, and can also be read by -    // keyframe update functions -    int  current_frame; -    int  time_left_in_frame; -    bool first_update_of_frame; -    bool last_update_of_frame; -    bool need_update; - -} keyframe_animation_t; - -extern GDisplay* LCD_DISPLAY; -extern GDisplay* LED_DISPLAY; - -void start_keyframe_animation(keyframe_animation_t* animation); -void stop_keyframe_animation(keyframe_animation_t* animation); -// This runs the next keyframe, but does not update the animation state -// Useful for crossfades for example -void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* state); - -// The master can set userdata which will be transferred to the slave -#ifdef VISUALIZER_USER_DATA_SIZE -void visualizer_set_user_data(void* user_data); -#endif - -// These functions have to be implemented by the user -// Called regularly each time the state has changed (but not every scan loop) -void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status); -// Called when the computer goes to suspend, will also stop calling update_user_visualizer_state -void user_visualizer_suspend(visualizer_state_t* state); -// You have to start at least one animation as a response to the following two functions -// When the animation has finished the visualizer will resume normal operation and start calling the -// update_user_visualizer_state again -// Called when the keyboard boots up -void initialize_user_visualizer(visualizer_state_t* state); -// Called when the computer resumes from a suspend -void user_visualizer_resume(visualizer_state_t* state); diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk deleted file mode 100644 index 4c961ac59d..0000000000 --- a/quantum/visualizer/visualizer.mk +++ /dev/null @@ -1,123 +0,0 @@ -# The MIT License (MIT) -#  -# Copyright (c) 2016 Fred Sundvik -#  -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -#  -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -#  -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -define ADD_DRIVER -    $(1)_DRIVER:=$(strip $($(1)_DRIVER)) -    $(1)_WIDTH:=$(strip $($(1)_WIDTH)) -    $(1)_HEIGHT:=$(strip $($(1)_HEIGHT)) -    ifeq ($($(1)_DRIVER),) -        $$(error $(1)_DRIVER is not defined) -    endif -    ifeq ($($(1)_WIDTH),) -        $$(error $(1)_WIDTH is not defined) -    endif -    ifeq ($($(1)_HEIGHT),) -        $$(error $(1)_HEIGHT is not defined) -    endif -    OPT_DEFS+=-D$(1)_WIDTH=$($(1)_WIDTH) -    OPT_DEFS+=-D$(1)_HEIGHT=$($(1)_HEIGHT) -    GFXDEFS+=-D$(1)_WIDTH=$($(1)_WIDTH) -    GFXDEFS+=-D$(1)_HEIGHT=$($(1)_HEIGHT) -    $(1)_DISPLAY_NUMBER:=$$(words $$(GDISP_DRIVER_LIST)) -    OPT_DEFS+=-D$(1)_DISPLAY_NUMBER=$$($(1)_DISPLAY_NUMBER) -    include $(TOP_DIR)/drivers/ugfx/gdisp/$($(1)_DRIVER)/driver.mk -endef - -GDISP_DRIVER_LIST:= - -SRC += $(VISUALIZER_DIR)/visualizer.c \ -	$(VISUALIZER_DIR)/visualizer_keyframes.c -EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR) -GFXLIB = $(LIB_PATH)/ugfx -VPATH += $(VISUALIZER_PATH) - -OPT_DEFS += -DVISUALIZER_ENABLE - -ifdef LCD_ENABLE -OPT_DEFS += -DLCD_ENABLE -ULIBS += -lm -endif - -ifeq ($(strip $(LCD_ENABLE)), yes) -    SRC += $(VISUALIZER_DIR)/lcd_keyframes.c -    ifeq ($(strip $(LCD_BACKLIGHT_ENABLE)), yes) -        OPT_DEFS += -DLCD_BACKLIGHT_ENABLE -        SRC += $(VISUALIZER_DIR)/lcd_backlight.c -        SRC += $(VISUALIZER_DIR)/lcd_backlight_keyframes.c -    endif -# Note, that the linker will strip out any resources that are not actually in use -SRC += $(VISUALIZER_DIR)/resources/lcd_logo.c -$(eval $(call ADD_DRIVER,LCD)) -endif - -ifeq ($(strip $(BACKLIGHT_ENABLE)), yes) -SRC += $(VISUALIZER_DIR)/led_backlight_keyframes.c -$(eval $(call ADD_DRIVER,LED)) -endif - -SRC += $(VISUALIZER_DIR)/default_animations.c - -include $(GFXLIB)/gfx.mk -# For the common_gfxconf.h -GFXINC += quantum/visualizer - -GFXSRC := $(patsubst $(TOP_DIR)/%,%,$(GFXSRC)) -GFXDEFS := $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) - -GDISP_LIST_COMMA=, -GDISP_LIST_EMPTY= -GDISP_LIST_SPACE=$(GDISP_LIST_EMPTY) $(GDISP_LIST_EMPTY) - -GDISP_DRIVER_LIST := $(strip $(GDISP_DRIVER_LIST)) -GDISP_DRIVER_LIST := $(subst $(GDISP_LIST_SPACE),$(GDISP_LIST_COMMA),$(GDISP_DRIVER_LIST)) - -GFXDEFS +=-DGDISP_DRIVER_LIST="$(GDISP_DRIVER_LIST)" - -ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") -    SRC += $(KEYMAP_PATH)/visualizer.c -else  -    VISUALIZER_1 := $(KEYBOARD_PATH_1)/visualizer.c -    VISUALIZER_2 := $(KEYBOARD_PATH_2)/visualizer.c -    VISUALIZER_3 := $(KEYBOARD_PATH_3)/visualizer.c -    VISUALIZER_4 := $(KEYBOARD_PATH_4)/visualizer.c -    VISUALIZER_5 := $(KEYBOARD_PATH_5)/visualizer.c - -    ifneq ("$(wildcard $(VISUALIZER_5))","") -        SRC += $(VISUALIZER_5) -    endif -    ifneq ("$(wildcard $(VISUALIZER_4))","") -        SRC += $(VISUALIZER_4) -    endif -    ifneq ("$(wildcard $(VISUALIZER_3))","") -        SRC += $(VISUALIZER_3) -    endif -    ifneq ("$(wildcard $(VISUALIZER_2))","") -        SRC += $(VISUALIZER_2) -    endif -    ifneq ("$(wildcard $(VISUALIZER_1))","") -        SRC += $(VISUALIZER_1) -    endif -endif - -ifdef EMULATOR -UINCDIR += $(TMK_DIR)/common -endif diff --git a/quantum/visualizer/visualizer_keyframes.c b/quantum/visualizer/visualizer_keyframes.c deleted file mode 100644 index 8f6a7e15a4..0000000000 --- a/quantum/visualizer/visualizer_keyframes.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include "visualizer_keyframes.h" - -bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    (void)state; -    return false; -} diff --git a/quantum/visualizer/visualizer_keyframes.h b/quantum/visualizer/visualizer_keyframes.h deleted file mode 100644 index c92ff16113..0000000000 --- a/quantum/visualizer/visualizer_keyframes.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#pragma once - -#include "visualizer.h" - -// Some predefined keyframe functions that can be used by the user code -// Does nothing, useful for adding delays -bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state); diff --git a/quantum/wpm.c b/quantum/wpm.c index e711e9fe73..cad4cefd5d 100644 --- a/quantum/wpm.c +++ b/quantum/wpm.c @@ -56,7 +56,7 @@ __attribute__((weak)) uint8_t wpm_regress_count(uint16_t keycode) {      } else if (keycode > 0xFF) {          keycode = 0;      } -    if (keycode == KC_DEL || keycode == KC_BSPC) { +    if (keycode == KC_DELETE || keycode == KC_BACKSPACE) {          if (((get_mods() | get_oneshot_mods()) & MOD_MASK_CTRL) || weak_modded) {              return WPM_ESTIMATED_WORD_SIZE;          } else {  | 
